Skip to main content

CSS Roadmap — What's Missing

Date: 2026-05-04 Companion to the Implementation Status page. This doc lists every CSS feature gap, organized by implementation priority.


🔴 Blockers — no support at all

These must be built from scratch to claim CSS feature parity.

Selectors in cascade

The stylesheet parser (stylesheet.rs:441) drops any rule containing combinators beyond descendant ( ). The query engine (query.rs) supports the full CSS Level 4 selector suite — all 4 combinators, 20+ pseudo-classes, attribute operators — but none of it flows through the cascade.

FeatureParserQuery engineCascade
>, +, ~ combinators❌ dropped✅ full❌ none
:is(), :where(), :not()❌ dropped✅ full❌ none
:has()❌ dropped✅ full (relative selectors)❌ none
:nth-child(), :nth-of-type()❌ dropped✅ full (+ of S syntax)❌ none
:disabled, :enabled, :checked❌ dropped✅ full❌ none
:required, :optional, :read-only, :read-write❌ dropped✅ full❌ none
:placeholder-shown❌ dropped✅ full❌ none
:focus-within, :focus-visible❌ dropped✅ full❌ none
:lang(), :dir()❌ dropped✅ full❌ none
:first-of-type, :last-of-type, :only-child, :empty❌ dropped✅ full❌ none
Multi-value attrs (~=, |=, ^=, $=, *=)❌ dropped✅ full❌ none
Case-insensitive attribute flag (i)❌ dropped✅ full❌ none

Fix: Replace stylesheet.rs's limited PseudoClass enum (6 variants) with query.rs's comprehensive one (30+ variants). Wire query.rs's ComplexSelector::matches_in_tree() into the cascade's matches_compound().

At-rules

The stylesheet parser at stylesheet.rs:310 skips every @-prefixed block except @media.

At-ruleStatus
@media✅ fully implemented (width/height/orientation, min/max, not)
@keyframes❌ not parsed — no animation engine
@font-face❌ not parsed — no font-face loading pipeline
@import❌ not parsed — no CSS import resolution
@supports❌ not parsed
@layer❌ not parsed — no cascade-layer awareness
@scope❌ not parsed
@page❌ not parsed
@charset❌ not parsed (assumes UTF-8)

Pseudo-elements

::before and ::after are parsed by the query engine but always return no matches (query.rs:1103 rejects any compound with a pseudo-element). The stylesheet parser drops rules containing them. Zero rendering infrastructure exists for generated content.

Pseudo-elementParserQuery matchRenderer
::before✅ parsed❌ false❌ none
::after✅ parsed❌ false❌ none
::first-line✅ parsed❌ false❌ none
::first-letter✅ parsed❌ false❌ none
::placeholder❌ not parsed❌ none❌ none
::selection❌ not parsed❌ none❌ none
::marker❌ not parsed❌ none❌ none

Layout gaps

FeatureStatus
float: left/right❌ not even parsed — no property entry exists
display: table and friends⚠️ all 10 table Display variants parsed but fall through to block layout
Multi-column (column-count, column-width)⚠️ parsed as deferred longhands, never consumed by layout
flex-basis: content❌ not implemented
Baseline alignment in flex (align-items: baseline)⚠️ parsed, falls back to flex-start (flex.rs:1236)
Sticky positioning⚠️ parsed, degraded to relative

Animation & transitions

FeatureStatus
@keyframes❌ not parsed
Animation engine❌ none — animation-* properties parsed into 13 deferred longhands, never consumed
Transition engine❌ none — transition-* parsed into 5 deferred longhands, never consumed
animation-timeline (scroll-driven)⚠️ parsed as deferred longhand, no runtime
scroll-timeline⚠️ parsed as shorthand → deferred longhands
prefers-reduced-motion media query❌ not implemented

Media & container queries

FeatureStatus
prefers-color-scheme❌ not implemented (system colors always light-mode)
prefers-contrast❌ not implemented
prefers-reduced-motion❌ not implemented
@container / container-type / container-name⚠️ parsed as deferred longhands, no runtime

🟡 Partial — parsed but not consumed

These properties are parsed into the Style struct or stored as raw strings, but have no effect on layout or rendering.

Parsed as raw Option<String>

PropertyWhere storedGap
box-shadowStyle.box_shadow (style.rs:211)No shadow rendering pipeline
transformStyle.transform (style.rs:200)No transform application in layout or GPU
transform-originStyle.transform_origin (style.rs:202)No transform pipeline
transitionDeferred longhands (5 fields)No transition engine
animationDeferred longhands (13 fields)No animation engine
filterNot even parsed — silently droppedNo filter pipeline

Parsed but rendering pipeline missing

PropertyParser statusRendering status
linear-gradient()CssImage::Function(String)Zero pixels — no gradient rasterizer
radial-gradient()CssImage::Function(String)Zero pixels
conic-gradient()CssImage::Function(String)Zero pixels
outlineShorthand → 3 deferred longhandsNever rendered
text-shadowDeferred longhandNever consumed by paint
border-imageShorthand → 5 deferred longhandsNo border-image rendering path
background-originDeferred longhandNo effect — always padding-box origin
background-attachmentDeferred longhandfixed would require viewport-relative positioning

Color value gaps

ValueParserResolution
currentColorCssColor::CurrentColorReturns None at resolve time (color.rs:14) — borders without explicit color are invisible
color-mix()CssColor::Function(String)Returns None
lab() / lch() / oklab() / oklch()CssColor::Function(String)Returns None
color() functionCssColor::Function(String)Returns None
hwb() / light-dark()CssColor::Function(String)Returns None
System colorsResolved to fixed light-mode sRGBNo dark-mode awareness

Cascade gaps

FeatureStatus
revert keywordParsed as token but never applied — only used to skip animation-name parsing
revert-layer keywordSame as revert
:where() in cascadeNot in cascade PseudoClass enum — exists only in query engine
Multiple backgroundsNot supported — background-image is single Option<CssImage>, not Vec
z-index stacking contextsSorts siblings by value (3 tests pass), but no independent cross-branch stacking

Other partial features

FeatureStatus
gap in non-flex/grid contextsParsed but not consumed by block layout
display: inline / inline-block (author-set)IFC auto-detected from content, not driven by display value
Dashed/dotted on non-uniform rounded cornersCorners stay bare — only uniform-circular radii follow the curve
Border double/groove/ridge/inset/outset stylesRender as plain solid
<link rel="stylesheet">Field exists on Tree, parsed from HTML, but no HTTP fetch

🟠 Missing properties — not parsed at all

These CSS properties have no entry in the parser (apply_css_property), Style struct, or deferred longhands table.

PropertyNotes
text-overflowNo ellipsis/fade rendering
word-breakNo break-all/keep-all logic
vertical-alignUA sets it on inline elements but parser ignores it
object-fitImages use hardcoded contain/cover logic
object-positionNo positioning of replaced content
mix-blend-modeNo compositing support
isolationNo stacking context support
will-changeNo GPU hint system
containNo containment support
aspect-ratioNo intrinsic sizing ratio
scroll-behaviorNo smooth scrolling
scroll-snap-type / scroll-snap-alignNo snap-point system
scroll-margin-* / scroll-padding-*Parsed as deferred, never consumed
cursor (OS cursor shape)Parsed into Style.cursor, not applied to OS cursor
accent-colorNot parsed
caret-colorNot parsed
print-color-adjustNot parsed
hyphensNot parsed
tab-sizeNot parsed

🟢 What works

CSS-Cascade-3 ordering with specificity, !important band separation, inherit/initial/unset keywords, @media queries (width/height/orientation), calc()/min()/max()/clamp() with full AST, var()/custom properties with inheritance and cycle detection, complete Flexbox Level 1, complete CSS Grid, positioned layout (absolute/relative/fixed), full querySelector engine (CSS Level 4 selectors), 80+ parsed CSS properties with typed resolution.


Suggested implementation order

The shortest path to "full CSS producer-grade engine":

PriorityTaskImpact
1Port query engine selectors into cascade (:is, :where, :not, :nth-child, :checked, :disabled, combinators, attribute operators)Unlocks ~50% of modern CSS in one change
2Implement currentColor resolutionFixes invisible borders, text decorations, etc.
3Build gradient rasterizer (linear + radial + conic)Background images become visually useful
4Implement @keyframes + animation engineMotion design becomes possible
5Float layoutRequired for text-wrap-around-images layouts
6Table layout algorithmRequired for data tables
7Pseudo-element rendering (::before/::after)Generated content, clearfix, decorative elements
8box-shadow / text-shadow renderingVisual depth
9Multi-column layoutText-heavy page layouts
10Transforms (transform, transform-origin)Animations, layout adjustments
11++Remaining property gaps, @layer, @supports, @container, media queries, modern colorsEdge cases and modern CSS features