Supported CSS
Property names and values match the CSS spec exactly — no prefixes, no
-unity- renames. Both parsers (tokenizer and rule/property grammar) are
hand-rolled for full control over the supported subset and error reporting.
This page covers selectors, the cascade, values/units, and at-rules. The property surface is split across three sub-pages:
- CSS Layout —
display, box model, flexbox, grid, positioning, overflow/scrolling, logical axes. - CSS Visual — backgrounds, borders, gradients, shadows,
opacity,transform,filter,clip-path, masks. - CSS Text — fonts,
line-height, alignment, decoration,white-space, wrapping, ellipsis.
For the authoritative supported / partial / parse-only / missing matrix, see CSS_FEATURE_AUDIT.md and CSS_OPEN_GAPS.md at the repo root. This page is a readable overview, not a line-by-line conformance table.
Selectors
| Type | Examples |
|---|---|
| Simple | *, tag, .class, #id |
| Attribute | [name], [name=val], [name~=val], [name^=val], [name$=val], [name*=val] |
| Combinators | descendant (space), child >, adjacent +, general sibling ~ |
| Structural pseudo | :first-child, :last-child, :only-child, :nth-child(an+b), :nth-of-type, :empty, :not(...), :is(...), :where(...), :has(...), :lang(...), :dir(...) |
| State pseudo | :hover, :focus, :focus-visible, :focus-within, :active, :link, :visited, :any-link, :target, :scope, :disabled, :enabled, :checked, :default, :required, :optional, :valid, :invalid, :user-valid, :user-invalid, :in-range, :out-of-range, :read-only, :read-write, :placeholder-shown, :autofill, :root |
| Pseudo-elements | ::before / :before, ::after / :after, ::placeholder, ::selection, ::backdrop, ::marker |
Specificity follows the spec; !important is honored. State pseudo-classes
flip automatically off event-driven interaction state — no controller code.
Known divergence: :nth-child(... of <selector>) parses but the
of <selector> filter is dropped — the index counts all children. Use a more
specific selector instead.
Cascade & inheritance
- Real selector matching, specificity sorting, and source order.
inherit,initial,unsetresolve per spec.revert/revert-layerroll back to the appropriate lower-priority match across origin and layer (up to 4 chained hops;!importantinversion is not honored in v1).var(--name, fallback)with cycle detection; a cycle member refuses its own definition-level fallback (consumer-side fallback still rescues).- Cascade layers (
@layer) and nested rules (& > .child). - Shorthand expansion for
font,background,border,border-radius,flex,flex-flow,gap,inset,margin/padding,list-style,animation, the logical box/border shorthands, andall.
Values & units
- Lengths:
px,em,rem,%,vw,vh,vmin,vmax, and the other standard absolute/relative units.1px= 1 logical pixel;rem/emderive from a 16px base. - Functions:
calc(),min(),max(),clamp()— full arithmetic over lengths, percentages, and numbers.attr()(typed forms in the cascade/contentpath),env()(safe-area names pre-registered; host can register more viaEnvironmentVariables.Register). - Colors:
#hex,rgb()/rgba(),hsl()/hsla(), named colors,currentColor,color-mix(),light-dark(). Color math runs in linear space. - Container query units (
cqw,cqi, …) are not registered — use viewport units or explicit lengths.
At-rules
@import "path.css"— relative and Unity asset paths. Thelayer(name)/supports(cond)qualifiers parse but the spliced rules are not wrapped/gated (move those into the importing sheet).@font-face— full descriptor parsing (font-family,srcwithlocal()/format(), weight/style/stretch ranges,unicode-range,font-display). Runtime font-matching honors family + firsturl(); the finer descriptors are parse-only pending a font-selector pipeline.@media— full feature set:width/height,orientation,aspect-ratio,resolution,prefers-color-scheme,prefers-reduced-motion,hover,pointer, withand/or/not. Evaluated against the UI surface, not the OS window.@container—container-type: inline-size | size, named and unnamed, width/height/inline-size/block-size/orientation/aspect-ratio features, range form (width >= 320px),style(--prop)queries, nested conditions, andand/or/not. A freshcontainer-typeassignment may take 1–2 frames to settle (the v1 chicken-and-egg: it reads layout-after-previous-cascade size).@keyframes— see Animations & Transitions.@supports— reports Weva's actual support.@scope(CSS Cascade Level 6) — including nested scope chains.@property— descriptor parsing withinherits/initial-value/syntax;initial-valuecontainingvar()/env()is rejected per spec.@layer— cascade layers.@namespace— parses but no XML namespace map (prefixed selectors match on the local name).
Known divergences from Chrome
These are intentional or phase-scoped. The full list lives in PLAN.md §11 "Known v1 simplifications".
- Default font is Segoe UI, not Arial — intentional. Bare
sans-serifresolves to the bundled Segoe-UI-like face (≈1.36× normal line-height) rather than Chrome's Arial (≈1.15×). This is a locked product decision; the resulting uniform y-shifts vs. Chrome are accepted divergence, not bugs. See Text & Fonts. box-sizingdefault iscontent-box(the CSS initial value). Use* { box-sizing: border-box }for the common reset.line-height: normalresolves taller than Chrome for the same font-size (a consequence of the default-face metrics above).- Layout-specific simplifications (
position: stickysingle-axis,min-content/max-contenttreated asautoin flex, etc.) are listed on CSS Layout. - A set of properties parse cleanly but are intentionally inert or reduced —
mix-blend-modenon-normalvalues,animation-composition: add, 3D-transform properties,font-feature-settings,font-variant-numeric,font-size-adjust,font-synthesis-*, container-query units, and others. SeeAuthoringGuide.md§17 for the full "parses-but-inert" and "partial-support" lists.
Next: CSS Layout · CSS Visual · CSS Text
Weva