CSS parser false positives with modern CSS features (@container queries)
Summary
Yellow Lab Tools reports false positives on several rules when modern CSS features are used. After extensive testing across a production WordPress theme (35+ blocks, 60+ CSS files), I've identified multiple categories of inaccurate reporting that affect the global score and mislead developers into "fixing" things that aren't broken.
Environment
- YLT public instance: https://yellowlab.tools
- Test URL: production WordPress site with CSS splitting, container queries, custom properties
- Date: March 2026
Issue 1: CSS Syntax Error — @container queries reported as missing '}'
Rule: CSS syntax error (scored F, 0/100)
Reported: 4 offenders — missing '}' at various lines
Root cause: The CSS parser does not recognize @container queries (CSS Containment Level 3, supported by Chrome 105+, Firefox 110+, Safari 16+ — ~95% browser coverage). When encountering @container (min-width: 1025px) {, the parser fails to parse the at-rule, interprets the { as an error, and reports missing '}'.
Example:
/* This valid CSS triggers the error */
@container (min-width: 1025px) {
.boost-posts__grid {
grid-template-columns: repeat(3, 1fr);
}
}
Impact: Developers who rely on YLT scores may avoid using @container queries (a modern best practice for component-level responsiveness) or waste time investigating non-existent syntax errors.
Suggestion: Update the CSS parser to recognize @container as a valid at-rule, similar to @media and @supports.
Issue 2: Duplicated Selectors — false positives inside @container queries
Rule: Duplicated selectors (scored A, but inflated count)
Reported: Selectors like .boost-posts__grid (x2), .boost-stats__grid (x2), .boost-steps--horizontal .boost-steps__grid (x2) flagged as duplicates.
Root cause: Because the parser doesn't understand @container, it treats selectors inside different @container breakpoints as duplicates of their base counterparts. In reality, these are in completely different container query contexts:
/* Base */
.boost-posts__grid {
grid-template-columns: repeat(3, 1fr);
}
/* Inside @container — NOT a duplicate */
@container (max-width: 768px) {
.boost-posts__grid {
grid-template-columns: 1fr;
}
}
This is functionally identical to having the same selector in different @media queries, which YLT correctly does NOT flag as duplicates.
Issue 3: Redundant body selectors — false positive on body:not(...) patterns
Rule: Redundant body selectors (scored A, 95/100)
Reported: 4 offenders like body:not(.boost-layout-contained):not(.boost-layout-narrow)... .boost-shortcode-block
Root cause: YLT's rule is "body in a selector can generally be removed because an element is necessarily inside the body." This is correct for simple body .foo selectors, but not for body:not(.class) selectors where body is the target of :not() pseudo-classes, not a generic ancestor.
/* body is REQUIRED here — the :not() checks are ON the body element */
body:not(.boost-layout-contained):not(.boost-layout-narrow) .boost-shortcode-block {
width: 100vw !important;
}
Removing body would make :not() apply to any ancestor, completely breaking the layout logic.
Suggestion: Exclude body selectors from this rule when body is combined with pseudo-classes (:not(), :has(), .class, #id, [attr]).
Issue 4: height: 100vh; height: 100dvh reported as duplicated property
Rule: Duplicated properties
Reported: Property height duplicated in .boost-header__mobile
Root cause: This is a standard progressive enhancement pattern:
.element {
height: 100vh; /* Fallback for older browsers */
height: 100dvh; /* Modern dynamic viewport height */
}
Browsers that don't support dvh ignore the second declaration and use vh. This is identical to how background: #fff; background: rgba(255,255,255,0.9) works — intentional fallback, not a mistake.
Suggestion: Don't flag consecutive declarations of the same property when the values use different units or functions (progressive enhancement pattern).
Summary of impact
These false positives can mislead developers into:
- Avoiding
@container queries (a W3C standard since 2023)
- Removing necessary
body:not() specificity patterns
- Removing progressive enhancement fallbacks
- Investigating non-existent CSS syntax errors
YLT is an excellent tool — these suggestions would make it even more accurate for modern CSS codebases.
Thank you for building and maintaining it!
CSS parser false positives with modern CSS features (@container queries)
Summary
Yellow Lab Tools reports false positives on several rules when modern CSS features are used. After extensive testing across a production WordPress theme (35+ blocks, 60+ CSS files), I've identified multiple categories of inaccurate reporting that affect the global score and mislead developers into "fixing" things that aren't broken.
Environment
Issue 1: CSS Syntax Error —
@containerqueries reported asmissing '}'Rule: CSS syntax error (scored F, 0/100)
Reported: 4 offenders —
missing '}'at various linesRoot cause: The CSS parser does not recognize
@containerqueries (CSS Containment Level 3, supported by Chrome 105+, Firefox 110+, Safari 16+ — ~95% browser coverage). When encountering@container (min-width: 1025px) {, the parser fails to parse the at-rule, interprets the{as an error, and reportsmissing '}'.Example:
Impact: Developers who rely on YLT scores may avoid using
@containerqueries (a modern best practice for component-level responsiveness) or waste time investigating non-existent syntax errors.Suggestion: Update the CSS parser to recognize
@containeras a valid at-rule, similar to@mediaand@supports.Issue 2: Duplicated Selectors — false positives inside
@containerqueriesRule: Duplicated selectors (scored A, but inflated count)
Reported: Selectors like
.boost-posts__grid (x2),.boost-stats__grid (x2),.boost-steps--horizontal .boost-steps__grid (x2)flagged as duplicates.Root cause: Because the parser doesn't understand
@container, it treats selectors inside different@containerbreakpoints as duplicates of their base counterparts. In reality, these are in completely different container query contexts:This is functionally identical to having the same selector in different
@mediaqueries, which YLT correctly does NOT flag as duplicates.Issue 3: Redundant body selectors — false positive on
body:not(...)patternsRule: Redundant body selectors (scored A, 95/100)
Reported: 4 offenders like
body:not(.boost-layout-contained):not(.boost-layout-narrow)... .boost-shortcode-blockRoot cause: YLT's rule is "body in a selector can generally be removed because an element is necessarily inside the body." This is correct for simple
body .fooselectors, but not forbody:not(.class)selectors wherebodyis the target of:not()pseudo-classes, not a generic ancestor.Removing
bodywould make:not()apply to any ancestor, completely breaking the layout logic.Suggestion: Exclude
bodyselectors from this rule whenbodyis combined with pseudo-classes (:not(),:has(),.class,#id,[attr]).Issue 4:
height: 100vh; height: 100dvhreported as duplicated propertyRule: Duplicated properties
Reported:
Property height duplicated in .boost-header__mobileRoot cause: This is a standard progressive enhancement pattern:
Browsers that don't support
dvhignore the second declaration and usevh. This is identical to howbackground: #fff; background: rgba(255,255,255,0.9)works — intentional fallback, not a mistake.Suggestion: Don't flag consecutive declarations of the same property when the values use different units or functions (progressive enhancement pattern).
Summary of impact
These false positives can mislead developers into:
@containerqueries (a W3C standard since 2023)body:not()specificity patternsYLT is an excellent tool — these suggestions would make it even more accurate for modern CSS codebases.
Thank you for building and maintaining it!