Let a rail hide when collapsed instead of narrowing
Plan step 25 (navigation Missing): M3's "Expanded behavior | Hide when collapsed" was only implicit below `medium` in the adaptive rail. `<x-navigation-rail hide-when-collapsed>` (collapsible and adaptive rails) takes the rail out of the layout when it is collapsed; `$store.rail.show()` from an app-bar menu button brings it back expanded over a scrim, sliding in, and its own menu button docks it again. It does not reach the bands where the window, not the visitor, collapses a rail (below `medium` for collapsible, `medium` for adaptive), since M3's collapsed rail may never hide. Every `rail-collapsed` branch now stops while the rail is open. `<x-app-shell hide-rail-when-collapsed>` exposes it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
a5acbe7f6b
commit
9c047a8fb1
@@ -48,12 +48,14 @@
|
||||
* in the rail: those have to beat a utility, and a layer never does.
|
||||
*/
|
||||
|
||||
/* Every branch below reads `:not([data-open])`: a rail open over a scrim is drawn expanded whatever
|
||||
made it collapsed, which only `hide-when-collapsed` can bring about outside the modal modes. */
|
||||
@custom-variant rail-collapsed {
|
||||
&:where([data-navigation-rail='collapsed'], [data-navigation-rail='collapsed'] *) {
|
||||
@slot;
|
||||
}
|
||||
|
||||
&:where([data-rail='collapsed'] [data-navigation-rail='collapsible'], [data-rail='collapsed'] [data-navigation-rail='collapsible'] *) {
|
||||
&:where([data-rail='collapsed'] [data-navigation-rail='collapsible']:not([data-open]), [data-rail='collapsed'] [data-navigation-rail='collapsible']:not([data-open]) *) {
|
||||
@slot;
|
||||
}
|
||||
|
||||
@@ -64,7 +66,7 @@
|
||||
/* Below `medium` a 220–360px rail would be most of the screen, so a rail whose width is the
|
||||
visitor's choice is held collapsed there whatever they chose. */
|
||||
@media (width < 37.5rem) {
|
||||
&:where([data-navigation-rail='collapsible'], [data-navigation-rail='collapsible'] *) {
|
||||
&:where([data-navigation-rail='collapsible']:not([data-open]), [data-navigation-rail='collapsible']:not([data-open]) *) {
|
||||
@slot;
|
||||
}
|
||||
}
|
||||
@@ -80,14 +82,14 @@
|
||||
`data-rail-auto`, which <x-theme-script> sets while nothing is stored, stands for "no
|
||||
choice yet" and the class's own default applies. */
|
||||
@media (52.5rem <= width < 75rem) {
|
||||
&:where(:is([data-rail='collapsed'], [data-rail-auto]) [data-navigation-rail='adaptive'], :is([data-rail='collapsed'], [data-rail-auto]) [data-navigation-rail='adaptive'] *) {
|
||||
&:where(:is([data-rail='collapsed'], [data-rail-auto]) [data-navigation-rail='adaptive']:not([data-open]), :is([data-rail='collapsed'], [data-rail-auto]) [data-navigation-rail='adaptive']:not([data-open]) *) {
|
||||
@slot;
|
||||
}
|
||||
}
|
||||
|
||||
/* Large and extra-large (from 1200): expanded to begin with, which is what M3 prefers there. */
|
||||
@media (width >= 75rem) {
|
||||
&:where([data-rail='collapsed'] [data-navigation-rail='adaptive'], [data-rail='collapsed'] [data-navigation-rail='adaptive'] *) {
|
||||
&:where([data-rail='collapsed'] [data-navigation-rail='adaptive']:not([data-open]), [data-rail='collapsed'] [data-navigation-rail='adaptive']:not([data-open]) *) {
|
||||
@slot;
|
||||
}
|
||||
}
|
||||
@@ -239,6 +241,18 @@
|
||||
--navigation-rail-collapsed-width: 5rem;
|
||||
}
|
||||
|
||||
/* "Expanded behavior | Hide when collapsed" (the reference's Navigation rail § Variants and
|
||||
configurations): instead of narrowing, the rail leaves the layout entirely — for an
|
||||
immersive page — and comes back over it when a menu button somewhere else, the app bar's,
|
||||
calls `$store.rail.show()`. It is the *expanded* rail that hides, which is why what comes
|
||||
back is the expanded rail: "collapsed rail may not hide", and the two bands where a window
|
||||
size class rather than the visitor collapses one are given back below. */
|
||||
[data-navigation-rail][data-hide-when-collapsed] {
|
||||
@variant rail-collapsed {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* There is no room for a label under the 56px indicator at 80px, so a narrow rail is the icons
|
||||
alone. The label is taken out of the drawing, not out of the page: it is what names the
|
||||
destination for a screen reader. */
|
||||
@@ -381,6 +395,72 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* A rail that hides when collapsed is in the same position: nothing is left in the layout for
|
||||
it to grow out of, so it takes the compact window's slide-in. The whole treatment is under
|
||||
the `rail-collapsed` variant, which stops the moment the rail is open — that is what makes
|
||||
it the expanded rail that comes back, on the rule above. */
|
||||
[data-navigation-rail][data-hide-when-collapsed] > [data-navigation-rail-panel] {
|
||||
@variant rail-collapsed {
|
||||
display: none;
|
||||
translate: -100% 0;
|
||||
transition:
|
||||
translate var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-easing-emphasized-accelerate),
|
||||
display var(--md-sys-motion-effects-default-duration) allow-discrete;
|
||||
|
||||
&:dir(rtl) {
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-navigation-rail][data-hide-when-collapsed][data-open] > [data-navigation-rail-panel] {
|
||||
display: flex;
|
||||
translate: 0 0;
|
||||
transition:
|
||||
translate var(--md-sys-motion-spatial-default-duration) var(--md-sys-motion-easing-emphasized-decelerate),
|
||||
display var(--md-sys-motion-spatial-default-duration) allow-discrete;
|
||||
|
||||
@starting-style {
|
||||
translate: -100% 0;
|
||||
}
|
||||
|
||||
&:dir(rtl) {
|
||||
translate: 0 0;
|
||||
|
||||
@starting-style {
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The two bands the configuration does not reach, because there it is the window and not the
|
||||
visitor that collapses the rail: below `medium` for a collapsible rail — where a rail is
|
||||
held at its collapsed width anyway — and `medium` itself for the adaptive one, which M3
|
||||
gives a collapsed rail. (Below `medium` the adaptive rail is already away, over the page,
|
||||
and the block above it says so.) resources/js/navigation.js reads the same two numbers, so
|
||||
the menu button and the drawing agree at every width. */
|
||||
@media (width < 37.5rem) {
|
||||
[data-navigation-rail='collapsible'][data-hide-when-collapsed] {
|
||||
width: var(--navigation-rail-collapsed-width);
|
||||
}
|
||||
|
||||
[data-navigation-rail='collapsible'][data-hide-when-collapsed] > [data-navigation-rail-panel] {
|
||||
display: flex;
|
||||
translate: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (37.5rem <= width < 52.5rem) {
|
||||
[data-navigation-rail='adaptive'][data-hide-when-collapsed] {
|
||||
width: var(--navigation-rail-collapsed-width);
|
||||
}
|
||||
|
||||
[data-navigation-rail='adaptive'][data-hide-when-collapsed] > [data-navigation-rail-panel] {
|
||||
display: flex;
|
||||
translate: none;
|
||||
}
|
||||
}
|
||||
|
||||
[data-navigation-rail-scrim] {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
|
||||
Reference in New Issue
Block a user