본문으로 건너뛰기

CSS Property Mapping

CSS → Grida IR property mapping table and TODO tracker.

Status key: ✅ mapped | ⚠️ partial | 🔧 IR exists, not wired | ❌ IR missing | 🚫 out of scope

Import pipelines: HTML import (crates/grida-canvas/src/html/), SVG import (via usvg, crates/grida-canvas/src/svg/).


Box Model & Sizing

CSS PropertyGrida IR FieldStatusNotes
widthLayoutDimensionStyle.layout_target_widthpx only; % not resolved
heightLayoutDimensionStyle.layout_target_heightpx only
min-widthLayoutDimensionStyle.layout_min_width
min-heightLayoutDimensionStyle.layout_min_height
max-widthLayoutDimensionStyle.layout_max_width
max-heightLayoutDimensionStyle.layout_max_height
padding (all sides)LayoutContainerStyle.layout_paddingEdgeInsets (top/right/bottom/left)
margin--Not in LayoutChildStyle
box-sizing--⚠️Assumed border-box; no explicit field
aspect-ratioLayoutDimensionStyle.layout_target_aspect_ratio🔧Field exists, CSS import not wired

Display & Layout

CSS PropertyGrida IR FieldStatusNotes
display: flexLayoutContainerStyle.layout_mode = Flex
display: blocklayout_mode = Flex (column)⚠️Approximated as flex column
display: none(element skipped)Node not emitted
display: inline--Treated as block
display: grid--No grid in LayoutMode
flex-direction (row/column)layout_direction
flex-direction (row-reverse/column-reverse)layout_direction⚠️Reverse info lost
flex-wraplayout_wrap
flex-wrap: wrap-reverselayout_wrap⚠️Reverse info lost
align-itemslayout_cross_axis_alignmentstart/center/end/stretch
justify-contentlayout_main_axis_alignmentstart/center/end/between/around/evenly/stretch
flex-growLayoutChildStyle.layout_grow
flex-shrink--Not in LayoutChildStyle; Taffy hardcodes 0.0
flex-basis--Not in IR
align-self--Not in LayoutChildStyle
order--Not in IR
gap / row-gap / column-gapLayoutContainerStyle.layout_gapDirection-aware mapping
position: absoluteLayoutChildStyle.layout_positioning = Absolute
position: relativeLayoutChildStyle.layout_positioning = Auto
position: fixed/sticky--No viewport-relative positioning
top/right/bottom/left--No offset in LayoutChildStyle

Background & Paint

CSS PropertyGrida IR FieldStatusNotes
background-colorPaint::Solid in fillshex/rgb/rgba/named
linear-gradient()Paint::LinearGradient
radial-gradient()Paint::RadialGradient
conic-gradient()Paint::SweepGradient
background-image: url()Paint::Image🔧IR exists, CSS import not wired
background-size--Not mapped
background-position--Not mapped
background-repeat--Not mapped
background-clip: text--No text-clip paint

Opacity & Blend

CSS PropertyGrida IR FieldStatusNotes
opacitynode.opacity
mix-blend-modeLayerBlendMode::Blend(BlendMode)All 16 modes

Border

CSS PropertyGrida IR FieldStatusNotes
border-widthStrokeWidth (Uniform or Rectangular)Per-side widths
border-colorPaints (strokes)Single color for all sides
border-style (solid/dashed/dotted)StrokeStyle.stroke_dash_array
border-radiusRectangularCornerRadiusPer-corner, elliptical
Per-side border colors--⚠️Only first visible side color used
border-image--No gradient/image stroke

Shadow & Effects

CSS PropertyGrida IR FieldStatusNotes
box-shadowFilterShadowEffect::DropShadowdx/dy/blur/spread/color
box-shadow: insetFilterShadowEffect::InnerShadow
text-shadowFilterShadowEffect::DropShadowOn TextSpan nodes; no spread
filter: blur()FeLayerBlur
filter: drop-shadow()FilterShadowEffect::DropShadow
backdrop-filter: blur()FeBackdropBlur🔧Code exists; Stylo servo mode blocks
filter: brightness()--No IR for non-blur filters
filter: contrast()--
filter: grayscale()--
filter: sepia()--
filter: hue-rotate()--
filter: invert()--
filter: saturate()--

Text

CSS PropertyGrida IR FieldStatusNotes
font-sizeTextStyleRec.font_size
font-weightTextStyleRec.font_weight
font-familyTextStyleRec.font_family
font-style: italicTextStyleRec.font_style_italic
colorTextSpanNodeRec.fills (Solid)Inherited
text-alignTextAlignleft/right/center/justify
line-heightTextLineHeight (Factor or Fixed)
letter-spacingTextLetterSpacing::Fixed
word-spacingTextWordSpacing::Fixed
text-transformTextTransformuppercase/lowercase/capitalize
text-decoration-lineTextDecorationRec.text_decoration_lineunderline/overline/line-through
text-decoration-colorTextDecorationRec.text_decoration_color
text-decoration-styleTextDecorationRec.text_decoration_stylesolid/double/dotted/dashed/wavy
text-decoration-thicknessTextDecorationRec.text_decoration_thickness🔧IR field exists; Stylo servo mode doesn't expose it (gecko-only)
text-decoration-skip-inkTextDecorationRec.text_decoration_skip_ink🔧IR field exists; Stylo servo mode doesn't expose it (gecko-only)
white-space--Not enforced
text-overflow--No IR field
vertical-align--No baseline offset
text-indent--No IR field
font-variant--Not mapped

Transform

CSS PropertyGrida IR FieldStatusNotes
transform (2D)AffineTransform🔧IR exists on every node; CSS import not wired
transform (3D)--IR is 2D only
transform-origin--No pivot point in IR

Overflow & Clip

CSS PropertyGrida IR FieldStatusNotes
overflowContainerNodeRec.clipSingle bool for both axes
overflow-x / overflow-yclip⚠️Merged to single bool
clip-path--No arbitrary clip shape

Visibility

CSS PropertyGrida IR FieldStatusNotes
visibility: hidden--Needs dedicated field; NOT opacity:0 (see below)
visibility: collapse--Same

Design note: visibility: hidden keeps layout space, suppresses paint, blocks pointer events, and is overridable by children (visibility: visible). None of these semantics match opacity: 0. The IR needs a per-node visible: bool field. Chromium implements this as a paint-skip flag, not a compositing trick.

Interaction (out of scope)

CSS PropertyStatusNotes
cursor🚫Runtime-only
pointer-events🚫Runtime-only
user-select🚫Runtime-only
transition / animation🚫Static format
@keyframes🚫Static format

IR Gaps

Properties blocked by missing schema fields, grouped by the change that would unblock them.

1. LayoutChildStyle expansion

Unblocks: flex-shrink, flex-basis, align-self, margin, order, top/right/bottom/left

Current LayoutChildStyle only has layout_grow: f32 and layout_positioning: LayoutPositioning. Adding shrink, basis, self-alignment, and margins would complete the flex-child model.

2. Visibility field

Unblocks: visibility: hidden, visibility: collapse

Needs a per-node visible: bool (or enum). Must be inherited and child-overridable. Distinct from opacity and active.

3. Grid layout

Unblocks: display: grid, grid-template-columns, grid-template-rows, grid-area, place-items

Requires a new LayoutMode::Grid and track definition types.

4. Non-blur filter functions

Unblocks: brightness(), contrast(), grayscale(), sepia(), hue-rotate(), invert(), saturate()

Could be modeled as a color matrix or individual filter effect variants.

5. Transform origin

Unblocks: transform-origin

Currently transforms are applied around (0, 0). A pivot point field on AffineTransform or the node would enable center/corner-based transforms.

6. Flex direction reverse

Unblocks: flex-direction: row-reverse / column-reverse, flex-wrap: wrap-reverse

Axis enum only has Horizontal/Vertical. Needs reverse variants or a separate bool.