Repository navigation
[style-value-parser] Fix media queries with a leading not - #2001
Open
henryqdineen wants to merge 1 commit into
Open
henryqdineen wants to merge 1 commit into
henryqdineen wants to merge 1 commit into
Conversation
In CSS a leading `not` negates the whole media query: `not all and (monochrome)` means `not (all and (monochrome))`. The parser bound the `not` to the media type alone, reading it as `(not all) and (monochrome)`. That used to round-trip back to the original string, so it went unnoticed. meta#1888 added media-type resolution, which simplifies the misread tree into wrong CSS: on main, `not all and (monochrome)` compiles to `not all` (never matches) and `not screen and (min-width: 100px)` to `print and (min-width: 100px)`. meta#1888 updated three snapshots to that output. 0.19.1 is also wrong when such a query is combined with other media queries on the same property: the leading `not` swallows the appended negations, or produces `(not not all)`. - Parse `not <type> and <condition>` as `not (<type> and <condition>)`. - Keep a standalone leading-`not` query in that form when serializing, so it still compiles to exactly what was written. The three meta#1888 snapshots go back to their original strings. Only combined queries are rewritten. - When resolving a negation, apply De Morgan before expanding the operand. Expanding first made `not screen and ((a) or (b) or ...)` grow combinatorially once combined with another query. - Parenthesize an `or` inside an `and` when serializing. Without this, `(min-width: 1px) and ((max-width: 2px) or (max-height: 3px))` lost its inner parentheses and became invalid (already broken on main). - Flatten nested `and` rules while resolving media types, so a media type from a negated later query moves to the front instead of ending up mid-query (`(max-width: 900px) and print and ...`, already broken on main for `not print, (max-width: 100px)`). Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
@henryqdineen is attempting to deploy a commit to the Meta Open Source Team on Vercel. A member of the Team first needs to authorize it. |
henryqdineen
marked this pull request as ready for review
October 31, 2026 19:29
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed / motivation ?
Since #1888 (unreleased), a media query with a leading
notcompiles to@media not all, which never matches. For example,@media not all and (monochrome)becomes@media not all, and #1888's snapshots assert that output. An agent noticed it. In CSS, a leadingnotnegates the whole query, but the parser read it as negating only the media type.The fix:
not <type> and <conditions>as a negation of the whole query, and print a standalone one as written.notinward before resolving media types, so the output grows linearly instead of exponentially.ornested inside anand, and flatten nestedands so a media type always ends up first.Linked PR/Issues
Follow-up to #1888. Related: #1199.
Additional Context
Inline snapshot tests were added in
media-query-transform-test.jsandtransform-stylex-create-test.js, and #1888's snapshots were reverted tonot all and (monochrome). I also compared the output againstmatchMediain Chromium on 6,000 random query lists:mainwas wrong on about 40%, this branch on none.Known gap, not changed here: a negated
min-heightbecomesmax-height: N.99px, which Chromium rounds to the breakpoint (same asmain; see #1858 and #1859). I'll fix that separately.Pre-flight checklist
🤖 Generated with Claude Code