17 KiB
Theming, CSS architecture & layout
Part of the theme chrome audit · snapshot 2026-08-24 · baselined on #5397 (navbar-redesign)
Sweep: 369 unique records across the four types, deep-dived 40, verified against the navbar-redesign checkout.
Already solved by #5397
-
#1897 — Return semi-transparent header background (kind: issue-not-planned; demand: 👍0, 3c)
- Asks for the frosted/translucent navbar that was removed; declined ("due to avoid any problems we had with transparent background") with a workaround of six
!importantrules against.content-body,.curtain::beforeand.has-sidebar— exactly the internals #5397 deletes. The single::beforesurface plus--vp-nav-backdrop-filter/--vp-nav-bg-colorreduces it to the documented two-line glass recipe. Residual not covered: the thread's second complaint ("scroll fast enough and content is briefly visible below navbar") is the scroll-state flash the planned scroll-driven-animations enhancement targets.
- Asks for the frosted/translucent navbar that was removed; declined ("due to avoid any problems we had with transparent background") with a workaround of six
-
#3383 — Fix transparent nav bar (kind: pr-unmerged; demand: 👍0, 5c)
- Config flag for a transparent navbar on non-home pages. Declined by kiaking: "Should be configurable by css variable customization… I think you already can by customizing
--vp-nav-bg-color." That prescribed route only truly works now. Carries one unbanked idea — kiaking's own "we should make navbar bg transparent by default onpagewhen there is nosidebarand nolocal-nav", which the new single state rule could express as one extra condition.
- Config flag for a transparent navbar on non-home pages. Declined by kiaking: "Should be configurable by css variable customization… I think you already can by customizing
-
#5097 — Allow overflow-x with horizontal scrolling in VPNav (kind: pr-unmerged; demand: 👍0, 4c)
- Superseded by the priority-plus
⋯menu. Also confirms the popover follow-up's value: the author was stuck on "the drop-down menus are no longer floating… I tried simplez-indexpotential fixes but they didn't work" — the scroll-container stacking trap that top-layer rendering removes structurally.
- Superseded by the priority-plus
Fits a planned follow-up
-
#3806 — sidebar uses native
for collapsible groups (kind: pr-open; demand: 👍0, 12c)- Enhancement:
details/summary+::details-content, plus the sidebar half of the rework. Adds requirements: (a) it is CONFLICTING and needs a rebase onto the newVPSidebarItem(native buttons viaed2bfb26), so the follow-up is now a markup swap plus animation, not an a11y fix; (b) behavior decision from review — brc-dd wants navigating to a page inside a collapsed group to auto-uncollapse it, which nativeopenstate must be driven to honour; (c) e2e tests in__tests__/e2e/multi-sidebar/index.test.tschange; (d) the animation gap that blocked it is what::details-content+transition-behavior: allow-discrete+interpolate-size: allow-keywordsnow closes.
- Enhancement:
-
#4847 — Accordions now use native details/summary (kind: pr-open; demand: 👍0, 5c)
- Same enhancement; two competing open PRs (both CONFLICTING, both last touched 2026-08-22) must be reconciled — pick one lineage before the
::details-contentwork starts.
- Same enhancement; two competing open PRs (both CONFLICTING, both last touched 2026-08-22) must be reconciled — pick one lineage before the
-
#3804 — sidebar: use native
for collapsible groups (kind: issue-open; demand: 👍0, 1c)- Acceptance criterion the PR body omits: Space-key toggling, asserted in the e2e disclosure tests.
-
#3517 — accessibility: interactive controls should not be nested (kind: issue-open; demand: 👍0, 1c)
- Requirement: whichever disclosure markup lands must not nest a control inside the link —
<summary>containing a link reproduces the same nesting, so the group-header-with-link case needs an explicit resolution.
- Requirement: whichever disclosure markup lands must not nest a control inside the link —
-
#2056 — feat(theme): move to css logical properties (kind: pr-unmerged; demand: 👍0, 2c)
- The prior attempt at the exact planned change, theme-wide. Adds: (a) the decline was not about RTL correctness or double-flip — Evan You rejected it as "a rather significant change for little perceived benefits… contributors are likely more familiar with transitional properties", so the follow-up needs a scope/benefit argument, which the RTL work (#5034/#5071) now supplies; (b) brc-dd's concrete regression from that attempt — "in outline that green border isn't been moved on scroll" — JS that reads/writes physical offsets breaks silently, so the outline marker is a required regression test.
-
#2794 — Disable automatically set direction in <html> (kind: issue-open; demand: 👍0, 3c)
- Enhancement: logical properties. Once the chrome is direction-agnostic, runtime
dirflipping becomes viable without a rebuild — currently blocked because physical properties plus the/*rtl:ignore*/escape hatches bake direction in at build time.
- Enhancement: logical properties. Once the chrome is direction-agnostic, runtime
-
#4359 — Local navigation dropdown misplaced without sidebar (kind: issue-open; demand: 👍0, 5c)
- Verified still present on
navbar-redesign:VPLocalNavOutlineDropdown.vue:172appliesleft: calc(var(--vp-sidebar-width) + 2rem)unconditionally at ≥60rem, andVPLocalNav.vue:90does the same withpadding-left. Requirement: the local nav needs the shared-geometry token the navbar just got (--vp-nav-col-offset, resolving to0pxwithout a sidebar).
- Verified still present on
-
#3433 — Use color-mix instead of multiple color CSS vars (kind: issue-open; demand: 👍0, 1c)
- Enhancement:
light-dark()token consolidation. The sole decline reason was the old Vite-era browser floor — invalidated: repo is onvite ^8.2.1,base.cssalready ships@layer __vitepress_base,color-mix()is Baseline widely available. Paircolor-mix()withlight-dark()in the same pass — brc-dd's own roadmap on #4425 names them together ("p3 colors / color-mix for brand colors?, font-relative units and dir-relative properties, zero specificity selectors").
- Enhancement:
-
#4471 — allow multiple different color modes in addition to light|dark (kind: issue-open; demand: 👍0, 0c)
- Constraint on
light-dark(), not a fit: it resolves solely throughcolor-scheme: light | dark, so consolidating tokens into it hard-codes the two-mode assumption. Keep a plain-token override seam (or scopelight-dark()to the chrome only).
- Constraint on
New candidates for future rework
-
#4125 — Put all styles in @layer for lowered specificity (kind: pr-unmerged; demand: 👍0, 2c)
- Declined only on the old browser floor; dead reason —
base.css:1already opens with@layer __vitepress_base(via completed #4425). Remaining work: extend layering frombase.cssto the chrome component styles. #5397 makes it safer: stable public class names (aliases kept) mean layering changes precedence without changing selectors.
- Declined only on the old browser floor; dead reason —
-
#2071 — Add support of Global Notification (kind: issue-open; demand: 👍0, 5c)
- Architectural finding:
--vp-layout-top-heightis threaded asvar(--vp-layout-top-height, 0px)through ten files, and users must inject head JS to set it. The single-surface pass is the moment to make the banner participate in flow, or derive the offset from the element instead of a JS-written variable. Also:--vp-z-index-layout-top: 40sits above--vp-z-index-nav: 30, so a sticky banner paints over the navbar.
- Architectural finding:
-
#1147 — Style error when custom max-width (kind: issue-not-planned; demand: 👍0, 8c)
- Cause named in-thread: "many style don't use css variables, instead use accurate numbers like
max-width: 688px". The same de-duplication #5397 did inside the navbar, applied toVPDoc/VPSidebar/VPContent, would make--vp-layout-max-widthand--vp-sidebar-widthactually load-bearing. bluwy's answer on #4669 confirms users are told to hand-edit.VPDoc .asideand.content-container.
- Cause named in-thread: "many style don't use css variables, instead use accurate numbers like
-
#1054 — Reduce layout shifts with classic scrollbars (kind: issue-open; demand: 👍0, 8c) (delta on known #5310)
- Delta the PR body's "
scrollbar-gutter: stable… not planned" reasoning does not account for: kiaking explicitly reversed on the modal case ("Modal thing should be fixed. Let's fix this issue then"), and zqianem tested the alternatives — "scrollbar-guttershows the gutter above the modal scrim", "overflow: overlayshows the scrollbar above the modal scrim and doesn't prevent the underlying content from scrolling". The scroll-lock/modal path needs a different mechanism.
- Delta the PR body's "
-
#1844 — fix(theme): avoid layout shift caused by scrollbar (kind: pr-open; demand: 👍5, 2c)
- Highest-👍 PR in the area; repeatedly rebased; author asked whether v2 is the moment. #5397 changes the calculus: its
100vwedits existed because the old chrome relied on viewport-width bleed — deleted. Rebased, the PR shrinks to roughly thebodyrule alone, and theoverflow-x: hiddenrisk is much reduced.
- Highest-👍 PR in the area; repeatedly rebased; author asked whether v2 is the moment. #5397 changes the calculus: its
-
#5198 — stabilize horizontal layout (html { overflow-y: scroll }) (kind: pr-open; demand: 👍0, 0c)
-
#4884 — Layout shift when search modal toggle (kind: issue-open; demand: 👍0, 0c)
- The concrete case kiaking already agreed to fix on #1054, still open. Belongs with whichever scroll-lock mechanism the above resolves to.
-
#2347 — feat(theme): add appearance transition feature (kind: pr-unmerged; demand: 58 reactions total: 🚀33 ❤️19 👀6; 11c)
- View Transitions circle-reveal on dark-mode toggle. Strongest community signal in this area. Declined on brand/trend grounds, but with an explicit opening: "it would be super cool if default theme has a cool way for users to hook in this kind of [effect]". Hooks since partly landed (
appearance.onChanged,appearance.disableTransition, open #4957), but brc-dd's caveat — "things might appear wonky if you're using the default theme" — was the six scattered nav background selectors. With one::beforesurface ("every state change below is color-only, so nothing ever moves"), a documented appearance-transition recipe is now tractable without shipping an opinionated animation. Gate onprefers-reduced-motion.
- View Transitions circle-reveal on dark-mode toggle. Strongest community signal in this area. Declined on brand/trend grounds, but with an explicit opening: "it would be super cool if default theme has a cool way for users to hook in this kind of [effect]". Hooks since partly landed (
-
#3313 — Consider not using opacity for any text content (kind: issue-open; demand: 👍0, 1c)
- Text dimmed via
opacityshows overlapping glyph strokes in some Persian/Arabic fonts, especially dark mode. Fits the token pass: dedicatedcolor-mix()-derived tokens fix the artifact and remove an opacity-induced stacking context. RTL-adjacent correctness item.
- Text dimmed via
-
#5209 — New CSS custom properties (kind: issue-not-planned; demand: 👍0, 0c)
- Maintainer left an explicit opening on the close of its PR #5211: "create a separate PR if parts regarding line-height are still relevant". Line-height is the one uncovered gap left in the custom-property surface.
-
#1764 — Navbar is not sticky in mobile breakpoint (kind: issue-not-planned; demand: 👍1, 2c)
- Confirmed by design on the branch:
VPNav.vueisposition: relative,fixedonly at ≥60rem. The decline was made when a fixed mobile bar meant fighting the curtain, the-100vwbleed andoverflow: hiddenparents. Those are gone, so revisiting is now cheap.
- Confirmed by design on the branch:
-
#3021 — Make the default theme compatible with 3rd-party CSS frameworks (kind: issue-open; demand: 👍1, 0c)
-
#3194 — TOC aside height problem (kind: issue-open; demand: 👍0, 0c)
- The aside is the last piece of chrome using viewport-relative geometry where container-relative would be correct. The PR body rules container queries out for the bar specifically; the aside is the opposite case and the natural place for them during the rework.
Not viable
- #4920 — CSS Modules in default theme (issue-not-planned; 👍0, 6c) — Stable user-targetable class names are required; #5397 strengthens that constraint.
- #3534 — breadcrumb (issue-open; 👍7, 11c) — [This sweep's view: blocker is the data model — markdown files don't know ancestors' titles. NB other sweeps dispute; resolved in the README.]
- #3160 — Full width layout for larger screens (issue-not-planned; 👍0, 2c) — Typographic decline unaffected.
- #4953 — Show "On this page" more often <1280px (issue-not-planned; 👍0, 2c) — ~80px recoverable; unaffected.
- #5178 — Cookie consent banner (issue-not-planned; 👍0, 1c) — Out of scope; layout side covered under #2071.
- #2938 — grayscale filter (issue-not-planned; 👍0, 2c) — One-line custom.css override.
- #4917 — nav icon repaint claims (issue-not-planned; 👍0, 4c) — Premise disputed with measurements.
- #4439 — --vp-c-text-1 bundle output (issue-not-planned; 👍0, 1c) — Fixed in later releases.
- #703 — font size follows browser settings (pr-unmerged; 👍0, 1c) — Superseded by the rem migration.
- #5211 — css custom properties for font sizes (pr-unmerged; 👍0, 1c) — Closed as unnecessary post-rem; line-height remainder tracked as #5209.
- #4413 — theme switcher tri-state (issue-not-planned; 👍1, 3c) and #5159 — auto detect system theme (pr-unmerged; 👍0, 0c) — Product decline ("keep the UI simple as a toggle") undisturbed.
- #2912 — Hide JS-required features if JS disabled (pr-open; 👍0, 9c) and #2680 (issue-not-planned; 👍0, 4c) — kiaking: "wouldn't it make more sense if we create a new JS free theme"; structural objection stands.
- #2133 — smooth scroll + duplicate cluster #978/#979/#981/#1002/#1449/#1544 — UI declined; motion-safety already handled (
base.css:232forcesscroll-behavior: auto !importantunder reduced motion). - #4215 — page width changes when scrollbar appears (issue-not-planned; 👍0, 3c) — Duplicate of #1054.