From b40a5af21d57d6a85923581165146dad8b89ea5d Mon Sep 17 00:00:00 2001 From: Universe Date: Mon, 6 Apr 2026 19:39:00 +0900 Subject: [PATCH 1/2] docs(htmlcss): expand CSS property reference and overhaul L0 fixtures - Expand Text & Font section in htmlcss.md from 11 to ~75 properties across 9 sub-sections (font variants, text layout, decoration, emphasis, writing modes, inline alignment, ruby) - Convert all 30 L0 fixtures from branded dark theme to probe-friendly B/W high-contrast palette for headless testing - Rename 7 fixtures to follow -[-] convention (flex-, filter-, inline-, list-, transform- domains) - Add grid-template.html fixture covering grid-template-columns/rows, fr units, repeat(), gap, spanning, auto-flow, and template-areas - Rewrite L0 README with domain taxonomy, authoring rules for probe-friendly fixture design, and updated template Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/wg/feat-2d/htmlcss.md | 316 ++++++++++++++++-- fixtures/test-html/L0/README.md | 268 +++++++++++---- fixtures/test-html/L0/box-dimensions.html | 13 +- fixtures/test-html/L0/box-margin.html | 54 +-- fixtures/test-html/L0/box-padding.html | 15 +- ...op-blur.html => filter-backdrop-blur.html} | 15 +- ...aint-filter-blur.html => filter-blur.html} | 16 +- ...yout-flex-column.html => flex-column.html} | 15 +- .../{layout-flex-row.html => flex-row.html} | 35 +- fixtures/test-html/L0/grid-template.html | 132 ++++++++ ...ine-elements.html => inline-elements.html} | 46 +-- fixtures/test-html/L0/layout-block.html | 13 +- .../test-html/L0/layout-display-none.html | 9 +- .../L0/{text-lists.html => list-style.html} | 8 +- fixtures/test-html/L0/mixed-card.html | 26 +- fixtures/test-html/L0/mixed-inline-style.html | 25 +- .../test-html/L0/paint-background-solid.html | 31 +- fixtures/test-html/L0/paint-blend-mode.html | 17 +- .../test-html/L0/paint-border-radius.html | 13 +- fixtures/test-html/L0/paint-border-style.html | 32 +- .../test-html/L0/paint-gradient-linear.html | 30 +- .../test-html/L0/paint-gradient-radial.html | 26 +- fixtures/test-html/L0/paint-opacity.html | 16 +- fixtures/test-html/L0/paint-shadow.html | 21 +- fixtures/test-html/L0/text-align.html | 11 +- fixtures/test-html/L0/text-color.html | 27 +- .../test-html/L0/text-decoration-full.html | 21 +- fixtures/test-html/L0/text-decoration.html | 7 +- .../test-html/L0/text-font-properties.html | 9 +- .../test-html/L0/text-letter-spacing.html | 11 +- fixtures/test-html/L0/text-line-height.html | 11 +- fixtures/test-html/L0/text-shadow.html | 21 +- .../L0/{transform.html => transform-2d.html} | 13 +- 33 files changed, 937 insertions(+), 386 deletions(-) rename fixtures/test-html/L0/{paint-backdrop-blur.html => filter-backdrop-blur.html} (87%) rename fixtures/test-html/L0/{paint-filter-blur.html => filter-blur.html} (86%) rename fixtures/test-html/L0/{layout-flex-column.html => flex-column.html} (93%) rename fixtures/test-html/L0/{layout-flex-row.html => flex-row.html} (85%) create mode 100644 fixtures/test-html/L0/grid-template.html rename fixtures/test-html/L0/{text-inline-elements.html => inline-elements.html} (79%) rename fixtures/test-html/L0/{text-lists.html => list-style.html} (97%) rename fixtures/test-html/L0/{transform.html => transform-2d.html} (93%) diff --git a/docs/wg/feat-2d/htmlcss.md b/docs/wg/feat-2d/htmlcss.md index c08c9ab6ca..31b3784e8a 100644 --- a/docs/wg/feat-2d/htmlcss.md +++ b/docs/wg/feat-2d/htmlcss.md @@ -104,19 +104,122 @@ Types from `cg::prelude` reused where they 100% align with CSS semantics: ### Text & Font -| CSS Property | Status | Notes | -| -------------------------------- | ------ | ----------------------------------------------------------- | -| `color` | ✅ | Inherited | -| `font-size` | ✅ | Computed px | -| `font-weight` | ✅ | 100–900 | -| `font-style` (italic) | ✅ | | -| `font-family` | ✅ | Generic families mapped to platform names | -| `line-height` | ✅ | normal, number, length | -| `letter-spacing`, `word-spacing` | ✅ | | -| `text-align` | ✅ | left, right, center, justify | -| `text-transform` | ✅ | uppercase, lowercase, capitalize | -| `text-decoration` | ✅ | underline, line-through, overline (bitfield — simultaneous) | -| `white-space` | ✅ | normal, pre, pre-wrap, pre-line, nowrap | +#### Color & Inheritance + +| CSS Property | Status | Notes | +| ------------ | ------ | --------- | +| `color` | ✅ | Inherited | + +#### Font Properties + +| CSS Property | Status | Notes | +| --------------------------- | ------ | ----------------------------------------- | +| `font` (shorthand) | ❌ | | +| `font-family` | ✅ | Generic families mapped to platform names | +| `font-size` | ✅ | Computed px | +| `font-weight` | ✅ | 100–900 | +| `font-style` | ✅ | italic | +| `font-stretch` | ❌ | | +| `font-size-adjust` | ❌ | | +| `font-kerning` | ❌ | | +| `font-optical-sizing` | ❌ | | +| `font-synthesis` | ❌ | Shorthand | +| `font-synthesis-weight` | ❌ | | +| `font-synthesis-style` | ❌ | | +| `font-synthesis-small-caps` | ❌ | | +| `font-variant` (shorthand) | ❌ | | +| `font-variant-ligatures` | ❌ | | +| `font-variant-caps` | ❌ | | +| `font-variant-numeric` | ❌ | | +| `font-variant-east-asian` | ❌ | | +| `font-variant-alternates` | ❌ | | +| `font-variant-position` | ❌ | | +| `font-variant-emoji` | ❌ | | +| `font-feature-settings` | ❌ | | +| `font-variation-settings` | ❌ | | +| `font-language-override` | ❌ | | + +#### Text Layout + +| CSS Property | Status | Notes | +| ----------------------------- | ------ | ------------------------------------------- | +| `line-height` | ✅ | normal, number, length | +| `letter-spacing` | ✅ | | +| `word-spacing` | ✅ | | +| `text-align` | ✅ | left, right, center, justify | +| `text-align-last` | ❌ | | +| `text-justify` | ❌ | | +| `text-indent` | ❌ | Field defined in FontProps, not extracted | +| `text-transform` | ✅ | uppercase, lowercase, capitalize | +| `white-space` | ✅ | normal, pre, pre-wrap, pre-line, nowrap | +| `word-break` | ❌ | | +| `overflow-wrap` / `word-wrap` | ❌ | | +| `line-break` | ❌ | | +| `hyphens` | ❌ | | +| `hyphenate-character` | ❌ | | +| `hyphenate-limit-chars` | ❌ | | +| `tab-size` | ❌ | | +| `text-overflow` | ❌ | Enum defined (Clip/Ellipsis), not extracted | +| `text-wrap` | ❌ | | +| `text-wrap-mode` | ❌ | | +| `text-wrap-style` | ❌ | | +| `hanging-punctuation` | ❌ | | +| `text-spacing-trim` | ❌ | | + +#### Text Decoration + +| CSS Property | Status | Notes | +| ----------------------------- | ------ | ----------------------------------------------------------- | +| `text-decoration` (shorthand) | ✅ | underline, line-through, overline (bitfield — simultaneous) | +| `text-decoration-line` | ✅ | | +| `text-decoration-style` | ⚠️ | Field defined, not extracted from Stylo | +| `text-decoration-color` | ⚠️ | Field defined, not extracted from Stylo | +| `text-decoration-thickness` | ❌ | | +| `text-decoration-skip-ink` | ❌ | | +| `text-underline-position` | ❌ | | +| `text-underline-offset` | ❌ | | + +#### Text Emphasis + +| CSS Property | Status | Notes | +| ------------------------ | ------ | ----- | +| `text-emphasis` | ❌ | | +| `text-emphasis-style` | ❌ | | +| `text-emphasis-color` | ❌ | | +| `text-emphasis-position` | ❌ | | + +#### Text Shadow + +| CSS Property | Status | Notes | +| ------------- | ------ | ------------------ | +| `text-shadow` | ❌ | Not in type schema | + +#### Writing Modes & BiDi + +| CSS Property | Status | Notes | +| ---------------------- | ------ | ----- | +| `direction` | ❌ | | +| `writing-mode` | ❌ | | +| `unicode-bidi` | ❌ | | +| `text-orientation` | ❌ | | +| `text-combine-upright` | ❌ | | + +#### Inline Layout & Alignment + +| CSS Property | Status | Notes | +| -------------------- | ------ | --------------------------- | +| `vertical-align` | ❌ | Enum defined, not extracted | +| `dominant-baseline` | ❌ | | +| `alignment-baseline` | ❌ | | +| `baseline-shift` | ❌ | | +| `initial-letter` | ❌ | | + +#### Ruby + +| CSS Property | Status | Notes | +| --------------- | ------ | ----- | +| `ruby-position` | ❌ | | +| `ruby-align` | ❌ | | ### Inline Elements @@ -160,19 +263,180 @@ Types from `cg::prelude` reused where they 100% align with CSS semantics: | `position: absolute` | ✅ | Via Taffy | | `z-index` | ⚠️ | Stored but not used for paint order | -### Not Yet Supported - -| Category | Properties | -| ----------------- | ------------------------------------------------------------------- | -| Background images | `background-image: url()`, `background-position`, `background-size` | -| Transform | `transform`, `transform-origin` | -| Box shadow inset | `box-shadow: inset` | -| Table layout | `display: table-row`, `table-cell` (proper grid) | -| Float | `float`, `clear` | -| Filter | `filter`, `backdrop-filter` | -| Clip/Mask | `clip-path`, `mask` | -| Outline | `outline` | -| Text | `text-indent`, `text-overflow`, `vertical-align` (sub/super) | +### Grid Layout + +| CSS Property | Status | Notes | +| ------------------------------------- | ------ | ---------------------------------------- | +| `display: grid` | ⚠️ | Taffy `Display::Grid`, no grid props yet | +| `grid-template-columns` | ❌ | | +| `grid-template-rows` | ❌ | | +| `grid-template-areas` | ❌ | | +| `grid-auto-columns`, `grid-auto-rows` | ❌ | | +| `grid-auto-flow` | ❌ | | +| `grid-column`, `grid-row` | ❌ | | +| `gap` (row-gap, column-gap) | ✅ | Flex/grid gap via Taffy | + +### Flexbox (detail) + +| CSS Property | Status | Notes | +| ----------------- | ------ | --------- | +| `flex-direction` | ✅ | Via Taffy | +| `flex-wrap` | ✅ | Via Taffy | +| `align-items` | ✅ | Via Taffy | +| `align-self` | ✅ | Via Taffy | +| `align-content` | ✅ | Via Taffy | +| `justify-content` | ✅ | Via Taffy | +| `justify-items` | ❌ | | +| `justify-self` | ❌ | | +| `flex-grow` | ✅ | Via Taffy | +| `flex-shrink` | ✅ | Via Taffy | +| `flex-basis` | ✅ | Via Taffy | +| `order` | ❌ | | + +### Sizing & Intrinsic Keywords + +| CSS Property | Status | Notes | +| ---------------------------- | ------ | -------------------------------- | +| `width`, `height` (%) | ⚠️ | px and auto only; % not resolved | +| `aspect-ratio` | ❌ | | +| `min-content`, `max-content` | ❌ | Intrinsic sizing keywords | +| `fit-content` | ❌ | | + +### Background (extended) + +| CSS Property | Status | Notes | +| ------------------------- | ------ | ----- | +| `background-position` | ❌ | | +| `background-size` | ❌ | | +| `background-repeat` | ❌ | | +| `background-origin` | ❌ | | +| `background-clip` | ❌ | | +| `background-attachment` | ❌ | | +| `background-image: url()` | ❌ | | + +### Box Shadow (detail) + +| CSS Property | Status | Notes | +| -------------------- | ------ | ----------------------------------- | +| `box-shadow` (outer) | ✅ | blur, spread, offset, border-radius | +| `box-shadow: inset` | ❌ | | +| Multiple shadows | ❌ | Only first shadow painted | + +### Positioning (extended) + +| CSS Property | Status | Notes | +| -------------------------------- | ------ | --------------------------------------- | +| `position: fixed` | ❌ | | +| `position: sticky` | ❌ | | +| `top`, `right`, `bottom`, `left` | ⚠️ | Stub in collect.rs, returns defaults | +| `z-index` | ⚠️ | Stored but not used for paint order | +| `float` | ❌ | Recognized in collect, no layout effect | +| `clear` | ❌ | Recognized in collect, no layout effect | + +### Transform & 3D + +| CSS Property | Status | Notes | +| --------------------- | ------ | ----- | +| `transform` | ❌ | | +| `transform-origin` | ❌ | | +| `perspective` | ❌ | | +| `backface-visibility` | ❌ | | + +### Filter & Effects + +| CSS Property | Status | Notes | +| ----------------- | ------ | ----- | +| `filter` | ❌ | | +| `backdrop-filter` | ❌ | | +| `clip-path` | ❌ | | +| `mask` | ❌ | | +| `mask-image` | ❌ | | + +### Outline + +| CSS Property | Status | Notes | +| ---------------- | ------ | ----- | +| `outline` | ❌ | | +| `outline-offset` | ❌ | | + +### Table Layout + +| CSS Property | Status | Notes | +| --------------------- | ------ | ------------------------------- | +| `display: table` | ⚠️ | Falls back to block flow | +| `display: table-row` | ⚠️ | Falls back to flex (faux-table) | +| `display: table-cell` | ⚠️ | Falls back to flex item | +| `border-collapse` | ❌ | | +| `border-spacing` | ❌ | | +| `table-layout` | ❌ | | +| `caption-side` | ❌ | | + +### Multi-column Layout + +| CSS Property | Status | Notes | +| -------------- | ------ | ------------------------------ | +| `columns` | ❌ | | +| `column-count` | ❌ | | +| `column-gap` | ✅ | Via Taffy gap (flex/grid only) | +| `column-rule` | ❌ | | +| `column-span` | ❌ | | +| `column-width` | ❌ | | + +### Generated Content & Counters + +| CSS Property | Status | Notes | +| -------------------------- | ------ | --------------------------------- | +| `content` (::before/after) | ❌ | Pseudo-elements not supported | +| `counter-reset` | ❌ | Internal counters for `
    ` only | +| `counter-increment` | ❌ | | +| `quotes` | ❌ | | + +### Interaction & UI + +| CSS Property | Status | Notes | +| ---------------- | ------ | ----------------------------- | +| `cursor` | ❌ | Not relevant for canvas embed | +| `pointer-events` | ❌ | Not relevant for canvas embed | +| `user-select` | ❌ | Not relevant for canvas embed | +| `resize` | ❌ | | +| `caret-color` | ❌ | | + +### Animation & Transition + +| CSS Property | Status | Notes | +| ------------ | ------ | ------------------ | +| `transition` | ❌ | Static render only | +| `animation` | ❌ | Static render only | + +### CSS Variables & Functions + +| Feature | Status | Notes | +| --------------------------- | ------ | -------------------- | +| Custom properties | ❌ | `var()` not resolved | +| `calc()` | ⚠️ | Stylo resolves to px | +| `clamp()`, `min()`, `max()` | ⚠️ | Stylo resolves to px | +| `env()` | ❌ | | + +### Replaced Elements + +| CSS Property | Status | Notes | +| --------------------- | ------ | ------------------------- | +| `object-fit` | ❌ | | +| `object-position` | ❌ | | +| `` rendering | ❌ | Images not loaded/painted | +| `` inline | ❌ | | +| ``, ``, ``, inline box decoration) | +| `list` | `
      `, `
        `, `list-style-type`, counters, nested lists | +| `table` | `display: table*`, `border-collapse`, `border-spacing` | +| `filter` | `filter`, `backdrop-filter` | +| `transform` | `transform`, `transform-origin`, `perspective` | +| `mask` | `clip-path`, `mask`, `mask-image` | +| `mixed` | Integration tests combining multiple domains | + +#### Naming examples -**Mixed** +``` +# --- paint --- +paint-background-solid.html background-color +paint-gradient-linear.html linear-gradient directions and multi-stop +paint-gradient-radial.html radial-gradient +paint-gradient-conic.html conic-gradient +paint-border-style.html solid, dashed, dotted +paint-border-style-double.html double, groove, ridge +paint-border-radius.html uniform, pill, circle, single-corner +paint-border-radius-elliptical.html elliptical (rx ≠ ry) +paint-shadow.html outer box-shadow +paint-shadow-inset.html inset box-shadow +paint-shadow-multiple.html multiple box-shadows +paint-opacity.html opacity values +paint-blend-mode.html mix-blend-mode values +paint-outline.html outline, outline-offset + +# --- layout --- +layout-block.html block flow +layout-display-none.html display: none skips elements +layout-position-relative.html position: relative with offsets +layout-position-absolute.html position: absolute +layout-overflow-hidden.html overflow: hidden clip +layout-visibility-hidden.html visibility: hidden/collapse + +# --- flex --- +flex-row.html flex-direction: row +flex-column.html flex-direction: column +flex-align-items.html align-items values +flex-gap.html row-gap, column-gap + +# --- box --- +box-dimensions.html width, height, min-*, max-* +box-margin.html margin all sides, collapsing, auto +box-padding.html padding all sides, shorthand + +# --- text --- +text-color.html color inheritance +text-align.html text-align values +text-font-properties.html font-size, weight, family, style +text-font-weight.html font-weight: 100–900 +text-line-height.html line-height: unitless, px +text-letter-spacing.html letter-spacing values +text-decoration.html underline, overline, line-through +text-decoration-full.html line + style + color combined +text-shadow.html text-shadow +text-whitespace-pre.html white-space: pre, pre-wrap, pre-line + +# --- inline --- +inline-elements.html , , + +# --- list --- +list-unordered.html
          disc/circle/square +list-ordered.html
            decimal, alpha +list-nested.html nested list counters + +# --- filter --- +filter-blur.html filter: blur() +filter-backdrop-blur.html backdrop-filter: blur() + +# --- transform --- +transform-2d.html translate, rotate, scale, skew +transform-origin.html transform-origin values + +# --- mask --- +mask-clip-path.html clip-path shapes + +# --- mixed --- +mixed-card.html realistic card combining many properties +mixed-inline-style.html style="" overriding stylesheet +``` -- `mixed-card.html` — realistic card with flex, padding, gap, bg, radius, border, shadow, typography -- `mixed-inline-style.html` — style="" attribute overriding stylesheet rules +--- ### Authoring Rules -1. **One concept per file** — each fixture targets a specific property group. -2. **Supported features only** — no margin, grid, tables, viewport units, position, or other unsupported CSS. See `crates/grida-canvas/src/html/TODO.md` for the unsupported list. -3. **Dark theme** — `background: #030712` on body, light text (`#e2e8f0`). -4. **Self-contained** — no external resources, no `