fix(sidebar): align a group's children with its label, not its icon - #2103
Merged
Conversation
A leading icon pushes the parent's own label right by the icon width
plus its `me-1` gutter - 24px at the default size. The nested list only
carries `ps-3`, which is 16px, so the children landed 8px to the *left*
of the label they belong to and the hierarchy read as broken.
Scoped with `:has()`, an idiom this file already uses, so it holds
however the icon arrived - a `pre` field on a data-file menu or a page
`icon` via `navigation.sidebarIcons` - and needs no template or config
change. Only the first nested list is shifted; everything deeper is
indented relative to it and follows.
Measured on a docs sidebar with icons on its top level, reading the
first visible glyph of each row:
row before after
Guides (icon) 104 104
Organization 96 104
Invite a Member 112 120
Organization now starts exactly where its parent's label does.
Verified to be a no-op without icons by removing the icons and
rebuilding: the ladder stays 80 / 96 / 112 and nested lists keep their
16px padding, so `:has()` never matches and existing sidebars are
untouched.
✅ Deploy Preview for gethinode-demo ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Collaborator
Author
|
🎉 This PR is included in version 3.13.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
LeonarddeR
pushed a commit
to LeonarddeR/hinode
that referenced
this pull request
Aug 1, 2026
Reported after gethinode#2103 shipped: the child items visibly shift on load. The sidebar HTML is cached per section and the collapse trail is expanded client side, so the nested list goes from display:none to visible after first paint. A `:has()` selector has to be re-resolved at that point, and a browser is free to paint the old `ps-3` first and correct it a frame later - which is exactly what the shift looks like. The template already knows whether the group has an icon, so it now emits `sidebar-nav-icon-indent` in place of `ps-3` and the rule is a plain class selector. The value is in the cached markup, so it is right from the first paint with no re-resolution and no dependence on when the collapse opens. Geometry is unchanged from gethinode#2103 - Guides 104, Organization 104, Invite a Member 120, with the icon-bearing lists at 24px and the rest at 16px. Groups without an icon keep `ps-3` exactly as before, now by emitting a different class rather than by failing to match a selector.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-on to #2102, found on a consuming site's deploy preview: with icons on, a group's children sit slightly left of the label they belong to, and the hierarchy reads as broken.
Cause
A leading icon pushes the parent's own label right by the icon width plus its
me-1gutter — 24px at the default size. The nested list only carriesps-3, which is 16px. The children are therefore 8px short of their parent's label.The fix
:has()is already used in this file (_sidebar.scss:540) and in_card.scss, so it introduces no new idiom.Scoping it this way means it holds however the icon arrived — a
prefield on a data-file menu, or a page'siconvianavigation.sidebarIcons— with no template or config change. Only the first nested list needs shifting; everything deeper is indented relative to it and follows.Evidence
Icon on the top level only, reading the first visible glyph of each row:
Guides(has icon)OrganizationInvite a MemberOrganizationnow starts exactly where its parent's label does, which was the reported problem.No-op without icons
The risk in touching a shared sidebar is the sidebars that were already fine. I removed the icons from the same site and rebuilt: the ladder stays 80 / 96 / 112 and nested lists keep their 16px padding, so
:has()never matches and nothing moves.pnpm testpasses.