Skip to content

fix(frontend): declare Vuetify cascade layer order before the split CSS chunks - #1

Merged
helldweller merged 2 commits into
mainfrom
fix/vuetify-layer-order
Oct 25, 2026
Merged

helldweller merged 2 commits into
mainfrom
fix/vuetify-layer-order

Conversation

@helldweller

Copy link
Copy Markdown
Owner

Problem

Since the Vuetify 3 → 4 bump (Jamyn/dispatch#326) every page renders under the app bar and the navigation drawer, and cards lose their internal padding. Dashboards show it most, but .v-main is wrong on every layout.

Cause

Vuetify 4 puts all of its styles in cascade layers, and the browser ranks layers by first appearance. The built index.html links Vite's split CSS chunks (VApp-*.css, VContainer-*.css, router-*.css, …) before index-*.css, and those chunks open @layer vuetify-components first, so vuetify-core ends up above it. The * { padding: 0; margin: 0 } reset that vuetify-md2-compat.css restores into vuetify-core.reset then outranks every component rule. On .v-main exactly two rules set padding, .v-main { padding: var(--v-layout-*) } and that * reset, and the reset wins.

Fix

Declare the layer order Vuetify documents in an inline <style> at the top of <head>, before any stylesheet, so the ranking no longer depends on how Vite orders the chunks. This is the pattern the Vuetify upgrade guide describes (vuetifyjs/vuetify#22848).

Verification

Measured on the production image (docker/Dockerfile, sample data loaded) with headless Chrome and the CDP matched-styles API:

before after
.v-main padding-top / padding-left 0 / 0 64px / 440px
.v-card-title padding 0 8px 16px
content container x 0 440

🤖 Generated with Claude Code

…SS chunks

Vuetify 4 (Netflix#326) puts every style in a cascade layer, and the browser ranks
layers by first appearance. The production index.html links Vite's split
CSS chunks (VApp-*.css, VContainer-*.css, router-*.css) before index-*.css,
and those chunks open `@layer vuetify-components` first, so `vuetify-core`
lands above it. The `* { padding: 0; margin: 0 }` reset that
vuetify-md2-compat.css restores into `vuetify-core.reset` then beats every
component rule: v-main loses its app-bar and drawer offsets, so the page
renders under the toolbar and the navigation drawer, and cards lose their
title padding. Every layout is affected, the dashboard is just where it
shows most.

Declare the order Vuetify documents in an inline <style> at the top of
<head>, before any stylesheet, so first appearance no longer depends on how
Vite orders the chunks. Verified on a production image: .v-main padding
goes from 0 to 64px top / 440px left and v-card-title padding returns.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@helldweller helldweller added the bug Something isn't working label Oct 25, 2026
@helldweller
helldweller requested a balanced review from Copilot October 25, 2026 12:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The fix is correct and verified, but the inline block is placed ahead of <meta charset>, an avoidable best-practice/robustness deviation that should be addressed before approval.

1 open issue
What changed in this PR

This PR fixes a layout regression introduced by the Vuetify 3 → 4 upgrade. In Vuetify 4 all styles live in CSS cascade layers, and the browser ranks layers by the order their names first appear. Because Vite's split CSS chunks (VApp-*.css, VContainer-*.css, …) open @layer vuetify-components before index-*.css names vuetify-core, vuetify-core wrongly outranked vuetify-components. That let the * { padding: 0; margin: 0 } reset (restored into vuetify-core.reset by vuetify-md2-compat.css) beat component rules, stripping .v-main of its app-bar/drawer offsets and cards of their padding. The fix pins the layer order up-front via an inline <style> at the top of <head>.

Changes:

  • Add an inline <style> block declaring @layer vuetify-core, vuetify-components, vuetify-overrides, vuetify-utilities, vuetify-final; before any stylesheet, matching Vuetify's documented order.
  • Add an explanatory comment documenting the root cause and rationale.
File Description
src/​dispatch/​static/​dispatch/​index.html Declares the Vuetify cascade-layer order inline at the top of <head> so layer priority is deterministic regardless of Vite's chunk ordering; adds a comment explaining the fix.

Review effort: Balanced

Comment thread src/dispatch/static/dispatch/index.html Resolved
…he meta tags

Review feedback on #1: the layer-order block only has to precede the
stylesheets Vite injects, not the meta tags, and the HTML spec wants the
charset declaration within the first 1024 bytes. Move the block below the
three meta tags so the charset stays the first element in <head>.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@helldweller
helldweller merged commit f5795cc into main Oct 25, 2026
8 checks passed
@helldweller
helldweller deleted the fix/vuetify-layer-order branch October 25, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants