Skip to content

[types] Five worked examples of shrinking the CSS type allowlists - #1886

Draft
henryqdineen wants to merge 5 commits into
hqd-stylex-css-types-cursorfrom
hqd-stylex-css-types-examples
Draft

henryqdineen wants to merge 5 commits into
hqd-stylex-css-types-cursorfrom
hqd-stylex-css-types-examples

Conversation

@henryqdineen

Copy link
Copy Markdown
Collaborator

What changed / motivation ?

Optional — #1882 through #1885 stand on their own. This is one worked example per allowlist from #1883, each its own commit, demonstrating the loop the tests exist for: cross an entry off the allowlist, the test says what to change, change it, the test goes green.

Commit Allowlist Change
Type overflowInline NOT_TYPED adds a property — Baseline high since 2021, and the counterpart of overflowBlock, which was already typed
Drop overflowBlockX NO_GRAMMAR deletes a property that is in no spec; the pair is overflow-block/overflow-inline
Drop outlineColor: invert KEPT_KEYWORDS removes a CSS 2.1 keyword only IE implemented
mixBlendMode: plus-darker/plus-lighter INCOMPLETE_UNIONS adds two keywords in the spec since Compositing Level 2
Eleven display keywords INCOMPLETE_UNIONS adds flow, table-caption, and the nine legacy flexbox/grid spellings

Each commit message quotes the failure that prompted it. (#1885 is a sixth example of the same loop, split out because it fixes a reported issue.)

Linked PR/Issues

Stacked on #1885.

Additional Context

mixBlendMode shows the trap to watch for. It aliased the shared blendMode, which backgroundBlendMode also uses — and the grammar says those two keywords belong to mix-blend-mode alone (mix-blend-mode: <blend-mode> | plus-darker | plus-lighter versus background-blend-mode: <blend-mode>#). Widening the shared alias would have wrongly allowed backgroundBlendMode: 'plus-darker'. Roughly half the remaining INCOMPLETE_UNIONS entries alias a shared type, so the grammar is what tells you whether a keyword belongs to the shared type or just the one property.

Typing overflowInline made a different test fail, because the alias it reuses is missing the same five keywords its siblings are. That commit therefore adds the property and its INCOMPLETE_UNIONS entry together — the tests catching a second-order gap introduced by closing a first-order one.

Remaining after these: NO_GRAMMAR 16, KEPT_KEYWORDS 19, INCOMPLETE_UNIONS 32, CLOSED_DESPITE_GRAMMAR 13, NOT_TYPED 24. positionArea alone accounts for 38 of the missing keywords.

Pre-flight checklist

🤖 Generated with Claude Code

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 11, 2026
@henryqdineen
henryqdineen added this pull request to stack #1887 September 11, 2026 03:13
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

workflow: benchmarks/perf

Comparison of performance test results, measured in operations per second. Larger is better.
yarn workspace v1.22.22
yarn run v1.22.22
$ node ./compare.js /tmp/tmp.lZD5ftvhWO /tmp/tmp.WYgdF7v2JW

Results Base Patch Ratio
babel-plugin: stylex.create
· basic create 585 578 0.99 -
· complex create 66 65 0.98 -
babel-plugin: stylex.createTheme
· basic themes 472 457 0.97 -
· complex themes 32 31 0.97 -
Done in 0.08s.
Done in 0.33s.

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

workflow: benchmarks/size

Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.
yarn workspace v1.22.22
yarn run v1.22.22
$ node ./compare.js /tmp/tmp.ITWXeyOr3u /tmp/tmp.ILTYGqPU0n

Results Base Patch Ratio
@stylexjs/stylex/lib/cjs/stylex.js
· compressed 1,535 1,535 1.00
· minified 5,166 5,166 1.00
@stylexjs/stylex/lib/cjs/inject.js
· compressed 1,793 1,793 1.00
· minified 4,915 4,915 1.00
benchmarks/size/.build/bundle.js
· compressed 496,650 496,650 1.00
· minified 4,847,840 4,847,840 1.00
benchmarks/size/.build/stylex.css
· compressed 99,735 99,735 1.00
· minified 740,755 740,755 1.00
Done in 0.08s.
Done in 0.35s.

henryqdineen and others added 5 commits September 10, 2026 23:15
Worked example of the `NOT_TYPED` loop: cross a property off the list, and the
test says what to write.

    overflowInline: Baseline high, so it is safe to use, but it is not typed.
    Its grammar is `visible | hidden | clip | scroll | auto |
    <-non-standard-overflow>`. Either add it to both type files, or list it in
    NOT_TYPED with a reason.

`overflow-inline` is the logical counterpart of `overflow-block`, which was
already typed, so this was an asymmetry rather than a decision. Baseline has
had it as widely available since September 2021. It takes the same values, so
it reuses the existing `overflowX` alias.

Typing it then failed the completeness check, because `overflowX` is missing
the same five keywords its siblings are -- `overlay` and four `-moz-scrollbars`
values. It gets the same `INCOMPLETE_UNIONS` entry as `overflow`,
`overflowBlock`, `overflowX` and `overflowY` until those are fixed together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Worked example of the `NO_GRAMMAR` loop, which points the other way: cross a
property off the list and the test asks you to justify it or delete it.

    overflowBlockX: css-tree has no grammar for this property. Either drop it
    from both type files, or add it to NO_GRAMMAR with a reason.

`overflow-block-x` is not a property in any specification. The pair is
`overflow-block` and `overflow-inline`, both of which are now typed, so this
was a typo with no valid values -- nothing could have been written in it that
produced working CSS.

Breaking in the sense that the key disappears from `CSSProperties`, but any
existing use was already emitting a declaration no browser understands.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Worked example of the `KEPT_KEYWORDS` loop, which operates on a keyword rather
than a property.

    outlineColor: 'invert' not in the CSS grammar. Either drop from both type
    files, or add to KEPT_KEYWORDS with a reason.

`outline-color: invert` is from CSS 2.1, where it inverted the colour
underneath the outline. The current grammar is `auto | <color>`; only IE ever
implemented `invert`, and browsers that see it now fall back to `currentColor`.

Kept the change to `outlineColor` alone. `invert` is not in the shared
`brStyle`-style aliases, so no other property is affected -- which is also why
this made a good first example. Narrowing something like `outline-style:
hidden` would mean expanding a shared alias, since `hidden` is legitimate for
every `border-*-style`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Worked example of the `INCOMPLETE_UNIONS` loop: cross an entry off, and the
test names the keywords the grammar allows but the type does not.

    mixBlendMode: the grammar allows 'plus-darker', 'plus-lighter' but the
    type does not. Either add to both type files, or list in
    INCOMPLETE_UNIONS.

Both have been in the spec since Compositing Level 2 and are what Safari's
`plus-lighter` transitions use.

The fix is not in the obvious place. `mixBlendMode` aliased the shared
`blendMode`, which `backgroundBlendMode` also uses -- and these two keywords
belong to `mix-blend-mode` alone:

    mix-blend-mode        <blend-mode> | plus-darker | plus-lighter
    background-blend-mode <blend-mode>#

Widening `blendMode` would have wrongly allowed `backgroundBlendMode:
'plus-darker'`, so the keywords go on `mixBlendMode` instead. Confirmed after
the change: `mixBlendMode: 'plus-lighter'` compiles and
`backgroundBlendMode: 'plus-lighter'` still does not.

This is the trap to watch for when emptying `INCOMPLETE_UNIONS`. Roughly half
the remaining entries alias a shared type, and the grammar is what says whether
a keyword belongs to the shared type or just the one property.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Worked example of the `INCOMPLETE_UNIONS` loop on the largest non-`positionArea`
entry.

    display: the grammar allows 'flow', 'table-caption', '-ms-inline-flexbox',
    '-ms-grid', '-ms-inline-grid', '-webkit-flex', '-webkit-inline-flex',
    '-webkit-inline-box', '-moz-inline-stack', '-moz-box', '-moz-inline-box'
    but the type does not.

`flow` and `table-caption` are plain omissions: `display: table-caption` is the
inner display type of a `<caption>` and has been supported everywhere for
years. The other nine are the legacy flexbox and grid spellings; StyleX already
typed `-webkit-box`, so the set was arbitrary rather than deliberate. csstype
carries all of them.

The `display` alias is used by no other property, so unlike `mixBlendMode` it
could be extended directly.

Typos still fail: after the change `display: 'flow'`, `'table-caption'` and
`'-webkit-box'` all compile, and `display: 'blok'` is still an error.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@henryqdineen
henryqdineen force-pushed the hqd-stylex-css-types-examples branch from 2185e51 to e275375 Compare September 11, 2026 03:15
@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
stylex Ignored Ignored Sep 11, 2026 3:15am UTC

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant