Skip to content

Contents sidebar carries two unprefixed width utilities, so its base width depends on Tailwind's emission order #130

Description

@mmcky

What happens

app/components/ContentsSidebar.tsx puts two unprefixed width utilities on the same element, split across two adjacent class strings:

'w-[350px] lg:w-[250px] 2xl:w-[350px]',
'h-screen w-[250px] z-[20] pt-[40px] pb-[90px] px-9',

The responsive line reads as the intent — 350px at base, 250px from lg, 350px again from 2xl. The trailing w-[250px] on the next line looks like a leftover from before that responsive line existed. Both are unprefixed, both land in Tailwind's base layer, and neither is more specific — so which one applies below lg is decided purely by which Tailwind emits last.

Measured against a make build-theme of current main:

band resolved width intended
base (< 1024px) 350px 350px
lg (1024–1535px) 250px 250px
2xl (≥ 1536px) 350px 350px

So the rendered result is correct today — but correct by accident. In the generated app.css, .w-\[250px\]{width:250px} sits at byte offset 56418 and .w-\[350px\]{width:350px} at 56468. The 350px rule wins only by landing later.

Why it matters

Tailwind orders arbitrary values by sorting them as strings, so [250px] sorts before [350px]. That holds while the two numbers keep their current relative order, but it is not a property anyone declared and nothing pins it.

Change the base width to anything sorting before 250px and the stale class silently takes over. Confirmed by editing the first utility to w-[150px] and rebuilding: .w-\[150px\] lands at offset 56372 and .w-\[250px\] at 56443, so the base band renders at 250px rather than the 150px just written. The edit looks like it did nothing, and there is no error anywhere to explain why.

Worth being precise about the blast radius, since the note that prompted this issue overstated it: the ambiguous band is the base one, and that band is snapshot-covered — sidebar-open runs on mobile-chrome at Pixel 5's 393px viewport, where a 350px→250px panel is far past maxDiffPixelRatio: 0.01. So a regression would be caught. It would surface as an unexplained mobile snapshot diff rather than as anything pointing at the real cause, which is the actual cost here.

Suggested direction

Delete the stale w-[250px] from the second class string. That leaves w-[350px] lg:w-[250px] 2xl:w-[350px] as the single, unambiguous source of the panel's width, and makes the emission-order dependency go away rather than merely documenting it.

Turned up while rebasing #123 onto main, in the course of checking a claim in that PR's description. Pre-existing, not caused by it.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions