Nested CSS rules starting with an element name are silently dropped on the phone #154
Closed
opened 2026-08-20 04:04:44 +00:00 by logan
·
2 comments
No Branch/Tag Specified
main
fix/146-stub-etxtbsy
fix/175-wizard-follows-the-library
fix/231-setter-rollback
fix/197-duplicate-column-label
docs/225-fixtures-wav-tags
docs/220-skill-check-scope
test/217-fixture-names-in-queue-selection
fix/216-riff-parse-allocation
fix/170-queue-header-action-names
fix/210-nav-sheet-scroll-affordance
docs/50-readme-landing-page
feat/65-art-prefetch-ahead
feat/71-more-as-a-bottom-sheet
feat/54-native-touch-feel
feat/67-entity-links-into-menus
test/196-visual-tier-gates
fix/138-ui-test-storage-leak
fix/104-wav-tags-read
fix/207-sheet-scroll-affordance
fix/204-ui-visual-update-filter
pi-agent-backlog-automation
63-touch-model-phase-2
63-android-touch-model
186-touch-targets-settings
186-touch-targets-page-header
187-seek-bar-hit-area
189-190-explore-correctness
135-android-underrun-instrumentation
51-android-small-screens
fix/171-phone-queue-scrim
fix/137-touch-only-affordances
fix/154-nested-css-check
feat/58-mini-player-progress-line
fix/66-album-page-scrolls-as-one
60-context-menu-action-sheet
64-android-system-volume
59-slim-the-mini-player
55-queue-as-a-screen
feat/57-drop-the-android-top-bar
feat/62-jobs-as-a-notification
fix/53-seek-bar-never-moves
fix/159-android-task-app-id
fix/52-android-activity-recreation-restarts-the-process
fix/150-expand-button-under-the-art
feat/42-inline-volume-and-centred-transport
fix/156-queue-selection-fixture-order
fix/151-fuse-the-scroll-guard-and-the-write
fix/43-queue-panel-selection
fix/143-top-bar-fits-its-window
feat/27-jobs-into-settings
feat/25-configurable-sidebar-tabs
feat/6-global-back-forward
fix/72-active-view-broadcast
fix/69-page-header-action-overflow
fix/quick-wins-batch
fix/118-in-library-clear
fix/61-mini-player-plain-text
fix/68-hover-affordances-pointer
fix/119-dev-headless-port
fix/130-issue-claim-user
fix/131-codegen-check-scope
feat/28-autotag-match-on-album
feat/17-demote-version-selector
feat/38-ownership-visibility
ci/115-manual-release
feat/34-icon-language
feat/7-full-tracklist-toggle
fix/16-tagwriter-totals
fix/unclaim-ca-certs
fix/unclaim-shell
ci/unclaim-on-close
docs/closing-keyword
docs/retire-stale-planning-docs
docs/issue-driven-workflow
integration/small-fixes
fix/small-issue-batch
fix/queue-toggle-state
fix/drag-count-badge
fix/album-card-year
fix/album-tracklist-heading
fix/seek-bar-clock-width
fix/explore-art-scanner-requests
chore/workflow-guardrails
v0.7.0
v0.6.0
v0.5.0
v0.4.0
v0.3.1
v0.3.0
v0.2.3
v0.2.2
v0.2.1
v0.2.0
v0.1.0
v0.0.1
v0.0.0
Labels
Clear labels
Area/Design
Area/Downloads
Area/Explore
Area/Library-UI
Area/Metadata
Area/Packaging
Area/Player
Area/Queue
Area/Settings
Area/Shell-Nav
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Platform/Android
Platform/Desktop
Breaking change that won't be backward compatible
Something is not working
Documentation changes
Improve existing functionality
New functionality
This is security issue
Issue or pull request related to testing
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Medium
3
The priority is medium
Priority
Low
4
The priority is low
Reviewed
Confirmed
1
Issue has been confirmed
Reviewed
Duplicate
2
This issue or pull request already exists
Reviewed
Invalid
3
Invalid issue
Reviewed
Won't Fix
3
This issue won't be fixed
Status
Blocked
1
Something is blocking this issue or pull request
Status
Need More Info
2
Feedback is required to reproduce issue or to continue work
Status
Abandoned
3
Somebody has started to work on this but abandoned work
Status
In Progress
Somebody is actively working on this right now
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: yonlu/yellowjacket#154
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Report
The device renders in Chrome 113 (
CLAUDE.md, "the phone is aChrome 113 WebView"), which predates relaxed CSS nesting (Chrome 120).
So a nested rule whose selector begins with a bare identifier is not a
parse error anyone would notice — it is silently dropped, on the
phone and only on the phone.
Three were live in
frontend/index.css, all inside.bottom-bar:The first is the one that matters: it is the
text-overflow: ellipsison the bottom bar's track title and artist, so on the device that
text has never truncated. Same class of fault as the
now-playingmarquee whose
text-overflowsat on the wrong box and had thereforenever produced an ellipsis in any mode — invisible to every assertion,
visible in a screenshot.
Those three are fixed in the PR for #23/#42, which rewrites that block
anyway. This issue is about the class, not those three.
Findings
& p,& now-playing,& audio-player.The
&form is valid in both the old and the new syntax, so there isno reason for any nested rule in this repo to omit it.
@mediais not nested.@media … { bottom-nav { … } }is a top-level rule and is fine — worth stating, because a naive
regex over the file flags those and they are the majority of the
matches.
frontend/src/**/*.tsfor the same shape insidecss`` literals returned only false positives (try {,return {`) with thecrude parser I used; a real one needs to know it is inside a tagged
template and inside a declaration block.
make ui-visualall run a current Chromium, where the rule appliesnormally. Only the device disagrees, and only in a screenshot.
Direction
Extend
make css-check, which already exists for a trap of exactlythis shape (a backtick that ends a
cssliteral early — silent, anddiagnosed a long way from the cause). It should fail on a nested rule
whose selector starts with an identifier, naming the file and line, and
say the fix is a leading
&.Two things to get right in the check: it must not flag rules directly
inside an at-rule (
@media,@supports,@container), and it shouldcover both
frontend/*.cssand thecsstagged templates incomponents, since the shadow-root stylesheets have the same constraint.
An alternative worth weighing first: a build-time transform (Lightning
CSS or PostCSS with a target of Chrome 113) would downlevel the
nesting rather than reject it, which fixes the class permanently and
covers whatever else the target browser lacks. That is a larger change
and adds a dependency; the check is the cheap version and matches how
this repo has handled the other silent-on-one-platform traps.
Taking this on branch
fix/154-nested-css-check.Approach is the Direction's cheap version: a second check under
make css-checkrather than a build-time downlevel, matching how theother silent-on-one-platform traps here are handled.
It covers
frontend/index.cssand thecssliterals infrontend/src/**/*.tsalike, and the detection walks blocks ratherthan matching lines, so both of the things the issue asks it to get
right fall out of one rule: a rule is nested when a style rule is
somewhere above it, which leaves
@media (…) { bottom-nav { … } }atthe top level alone and still flags one inside an at-rule that is
itself inside a rule. Strings and comments are read through, so a brace
in a
url()is not a block.The three live cases went with #23/#42, so the tree is clean and the
check would pass over an empty glob just as happily — hence a guard for
that and unit tests for the semantics, since no rendered tier can see
this class at all.
PR #180 is open and CI is green (
checkande2e, the latter over bothChromium and WebKit).
make css-checkcarries a second script,frontend/scripts/check-css-nesting.mjs, overindex.cssand thecssliterals alike, plus a lefthook pre-commit entry beside the existing
css-literalsone. Both of the things this issue asks it to get rightfall out of one rule — a rule is nested when a style rule is somewhere
above it — so a rule directly inside a top-level
@mediais notflagged and one inside an at-rule that is itself inside a rule is.
Watched failing before believing it: the three historical
&s removedfrom
index.css's bottom-bar block report exactly lines 282, 289 and293, and a
span { … }injected intopage-header's literal reportsits own line through the literal path.
The alternative this issue asks to weigh first — a build-time downlevel
targeting Chrome 113 — is deliberately not taken, and the trade is
written into CLAUDE.md rather than left in this thread.