Repository navigation
CSS Box Model
DOM img sizes now use computed width/height/min/max and box-sizing around intrinsic raster dimensions. HTML bounded size attributes supply hints before author cascade; CSS auto and global keywords override them. Percent widths use containing content width; font-relative units use computed font size. Definite heights and min/max ratio constraints are supported. Both-auto compatible bounds preserve ratio; conflicts and two explicit dimensions may stretch. Percentage heights await containing-height propagation. The existing viewport/ draw-height fitting policy still applies after CSS sizes and may reduce minimum sizes. Reference: CSS replaced size constraints.
Generated ::before/::after with display:block uses this same geometry path, including
empty-string decorated blocks. Definite heights set the box/flow height while content may
overflow; background/border geometry does not grow merely to contain that overflowing text.
OPBrowser owns the current block box-model pipeline from specified CSS through used layout geometry. Windows remains only a drawing backend for platform-neutral display-list commands.
The current block subset includes:
-
background-colorusing the current color parser; -
marginplusmargin-top/right/bottom/left; -
paddingpluspadding-top/right/bottom/left; -
width,min-width,max-width; -
height,min-height,max-height; -
box-sizing: content-box | border-box; -
borderandborder-top/right/bottom/left; -
border-width,border-style,border-colorand all side longhands; -
position: static | relative | absolute | fixedplustop/right/bottom/leftlength/percentage insets in the initial positioned-layout path.
Margin accepts auto, negative values and percentages. Padding and box sizes reject negative
used lengths. Supported dimensions include px, em, rem, in, cm, mm, Q, pt and pc; percentage
horizontal sizing resolves from the containing-block width. Unitless zero is accepted.
font-size additionally accepts percentages and the current absolute/relative size keywords.
Border styles currently implement only none and solid. Border widths accept lengths and
thin/medium/thick; border color accepts the normal color subset plus currentColor.
Shorthand and longhand declarations do not run in a hard-coded order: each affected side or
subproperty chooses its winner using the normal importance/source/specificity/source-order
cascade key.
For an ordinary non-replaced block, op_layout resolves:
containing block
-> percentage / auto / negative margins
-> width + min/max constraints
-> content-box or border-box interpretation
-> independent border edges
-> percentage / absolute padding
-> content box and available inline width
A specified width with both horizontal margins auto is centered. Auto width fills the
remaining containing width. Nested blocks, inline lines and images receive the resulting
content-box x/width. height and min/max height work for definite absolute values; a
percentage height is parsed but currently behaves auto-like when no definite containing
height is available, avoiding invented geometry.
The current rem conversion uses OPBrowser's initial root font-size baseline. Recomputing rem from an author-modified root font size remains later computed-value work.
Adjacent sibling block margins collapse. Two positive margins use the larger; two negative margins use the more negative; mixed signs combine the largest positive with the most negative. Whitespace-only DOM text between block siblings is discarded at the block-flow boundary so indentation/newlines do not create a fake anonymous line and break collapse.
Self-collapsing zero-height blocks now merge their top/bottom margins into the shared pending
margin set instead of advancing block-flow y. The detector can cross whitespace-only normal-flow
text, undecorated inline wrappers and display:contents, allowing an empty block nested inside an
inline-only wrapper and empty margin-transparent parent to collapse with surrounding sibling
margins. It is deliberately conservative: borders/padding/nonzero resolved height, preserved
whitespace, replaced content, generated before/after content or decorated inline wrappers fall
back to ordinary layout. General non-empty parent/first-child and parent/last-child margin collapse
still remains later work.
float:left/right now creates an out-of-flow float record without advancing the normal block-flow
cursor. clear:left/right/both advances a following block to the bottom of matching active floats.
display:flow-root and display:flow-root list-item establish an initial BFC: they avoid active
outer floats at their start edge, isolate descendant floats, include those floats in their natural
height and prevent child margins from collapsing through the BFC boundary. Floated tables keep the
table formatting algorithm inside float placement, while display:contents suppresses the
principal box and therefore ignores float placement on the contents element itself.
This is deliberately not complete CSS2 float layout yet. Text wrapping around floats, floating replaced images, complex left/right float packing, list markers and the full clearance/margin rules remain future work.
Relative positioning preserves the box's normal-flow slot and translates only the output emitted for that subtree, including decorations, text and images. Horizontal percentage offsets resolve against the containing width; vertical percentage offsets resolve when the direct containing block has a definite height.
Absolute and fixed block-level boxes are removed from normal flow. Absolute boxes resolve against
the nearest positioned ancestor's padding box, while fixed boxes resolve against the real viewport
width and height. Insets on all four sides accept px/percentage values when the corresponding axis
is definite. Bottom-only placement is supported, and opposing left/right or top/bottom insets can
stretch an auto-sized positioned block. Other positioned width:auto cases use the initial
shrink-to-fit path. Direct descendants can also resolve percentage heights from a definite
containing-block height, including min/max-clamped explicit heights.
Inline absolute/fixed boxes leave a zero-width marker in the inline sequence, so an auto-inset
static position uses the actual line cursor without forcing a line flush or consuming width.
Horizontal inline margins participate in inline advance, including negative values, while the
painted decoration excludes margin area. Initial display:inline-block creates one atomic inline
box backed by a local block/BFC layout and shrink-to-fit auto width. Replaced image sizing can also
consume intrinsic width/height/ratio metadata from the bounded SVG image slice.
When an in-flow block appears inside an inline, the inline arena now creates continuation fragments. The ending and continuing fragments suppress opposite logical horizontal edges, with LTR/RTL deciding which physical side is start/end. Empty intermediate continuation lines are retained only when the split sequence requires them, and relative-positioned inline ancestors carry their visual offset to split block/float descendants without moving normal flow. Large finite CSS lengths are retained at computed-value time and safely bounded when converted to used integer geometry. Non-replaced absolute/fixed boxes now solve auto horizontal/vertical margins after subtracting opposing insets and border-box dimensions. Both or one auto margin uses the remaining space, negative horizontal free space assigns the negative margin to the RTL/LTR end side, and negative vertical free space assigns it to the bottom. With fixed margins and overconstrained left/width/right, LTR anchors left and RTL anchors right; missing insets make auto margins zero.
Inline position:relative now establishes a containing rectangle for absolute children
from its measured first/last line-fragment padding edges, including fragments separated by
block-level descendants and separate formatting runs. Absolute children wait for complete
fragment geometry; nested deferred descendants are resolved after their parents. Undecorated
relative ancestors and LTR/RTL fragment edge anchoring work, and relative text/decorations
shift visually without changing surrounding flow. Block-level absolute/fixed elements with
unspecified horizontal insets use the right static edge of their hypothetical RTL flow rather
than automatically using viewport width; fixed insets continue to use the viewport.
Sticky positioning, full bidi/vertical writing, complex/replaced CSS2 positioned constraints, stacking/z-index and scroll-container interactions remain follow-up work. WPT Positioning v1 tracks 100 pinned cases across both implemented and deliberately unsupported families; it moved from 18/100 (18.00%) to 36/100 (36.00%) on the unchanged manifest.
display:flex and display:inline-flex now create an initial flex formatting context instead of
falling back to ordinary flow. The first slice implements the default single-line row: direct
in-flow elements become flex items, contiguous text becomes anonymous flex items, and nested
display:contents wrappers are recursively transparent during item generation. Contents wrappers
still carry inherited typography/color into descendant text but do not paint their own box.
Block flex participates as a block-level formatting context. inline-flex uses the same nested row
layout inside an atomic inline box and shrink-wraps its auto width. The existing block/inline
machinery lays out item contents, then their decorations, text, images and paint order are rebased
into the parent row.
This is not full Flexbox yet. Direction variants, wrapping, flexible lengths, ordering, alignment distribution and gaps remain follow-up work.
op_layout emits BoxDecoration records with border-box bounds, background color and four
independent border width/color pairs. op_paint expands them into one background FillRect
and up to four side-specific border FillRect commands. This keeps CSS knowledge out of the
Win32 painter.
RGBA box colors currently composite over the white page background. Proper stacking, background propagation and general alpha composition remain later rendering work.
- inline fragments clone edges on each wrapped line; sliced edge behavior remains later;
- nested text/image/empty/pseudo boxes reserve all ancestor edges and paint outer frames first;
- unavailable replacements preserve CSS boxes around zero natural sizes; nonempty alt uses text;
- self-collapsing empty-block propagation is implemented for conservative zero-geometry subtrees, but general parent/first-child and parent/last-child collapse remains incomplete;
- no
border-radius, outlines, shadows, background images or multiple backgrounds; - percentage height needs a definite-height containing-block propagation pass;
- table layout is implemented as a dedicated initial formatter with intrinsic content tracks,
colspan/rowspan, border-spacing, cell-edge collapse and table-cell baseline/top/middle/bottom
alignment; core anonymous-table fixup handles both missing child row/cell wrappers and orphan
table-internal sibling runs in normal flow without mutating the DOM, including initial orphan
caption and column-hint behavior. Structural
display:contentswrappers are transparent to this fixup when they expose table-internal descendants; wrappers around ordinary text/inline content remain style-transparent containers so inherited text properties are preserved. Auto tracks retain percentage column/cell constraints and table-layout:fixed on an explicit-width table uses column hints, first-row widths and remaining space without letting later-row content resize tracks. caption-side:top/bottom participates in wrapper flow outside the table border/background. display:inline-table is an atomic inline formatting context using the same table formatter, with shrink-to-fit auto width, margins, padding and borders. Atomic baseline/top/middle/bottom vertical-align moves the entire retained table box and contributes to line height. Complete CSS Tables overconstraint/min-width/percentage edge algorithms, non-cell collapsed-border precedence and deeper colgroup repair remain later; general inline sub/super/text-top/text-bottom/length/% alignment is not implemented yet; - floats, flexbox and positioning are initial subsets rather than complete specs; sticky positioning, flex direction/wrap/alignment/flexible sizing and CSS Grid remain unsupported;
- no complete stacking-context/background-propagation model.
Unsupported or invalid values are ignored before cascade winner selection, so a valid lower priority declaration can still win for the currently recognized properties.
The checked-in demo now exercises centered percentage-sized boxes, auto margins, min/max width, negative margin, em/percentage padding, border-box sizing, independent border sides and sibling margin collapsing:
target\release\op_browser.exe examples\css\index.html
Deterministic CSS/layout/paint/engine tests separately verify shorthand/longhand cascade, unit conversion, used coordinates, per-side paint commands, fixed border-box height and positive/negative sibling margin-collapse arithmetic.
Проект
Архитектура
Реализация
- CSS Syntax
- CSS Box Model
- Inline Layout
- Stylesheets
- Images
- Source Loading
- HTML Encoding
- Reflow
- Navigation
- JavaScript VM
- Request Filtering
Тесты и разработка