Morph the rail's FAB, and offer a divider, no fill and a width floor
M3 asks the rail to animate its FAB into an extended FAB as it expands; the documented pattern was two FABs swapped by `display`, so the collapsed one appeared at once while the rail's width was still springing. The header now takes one <x-fab label icon> whose label springs open and shut on the rail's own spring — and names it at both widths, where the collapsed FAB had needed a tooltip to have a name at all. M3 also lists two container treatments as optional that the library had neither of: `divider` draws the vertical divider on the page's edge, which is its own answer to a page scrolling under a fixed rail, and `fill="false"` drops the container colour. Neither reaches a rail open over a scrim. And a `collapsible` rail, whose width is the visitor's choice rather than the window's, is held to the collapsed 96px below `medium`, where M3 asks for a navigation bar instead. Plan: docs/plans/material-3-alignment.md, step 21 (navigation N-22, N-23, N-24). 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
1218371568
commit
7d14f2bd03
@@ -59,6 +59,14 @@
|
||||
@slot;
|
||||
}
|
||||
|
||||
/* 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'] *) {
|
||||
@slot;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 52.5rem) {
|
||||
&:where([data-navigation-rail='adaptive']:not([data-open]), [data-navigation-rail='adaptive']:not([data-open]) *) {
|
||||
@slot;
|
||||
@@ -215,6 +223,14 @@
|
||||
[data-navigation-rail='adaptive'] {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
/* "Compact → don't use a standard rail, use a navigation bar." A `collapsible` rail takes
|
||||
the width the visitor chose, which on a 360px screen would be two-thirds of it, so it
|
||||
is floored at the collapsed 96px. `collapsed` and `expanded` mean what they say and are
|
||||
left alone: wrap one in a `medium:` element if it must not show on a phone. */
|
||||
[data-navigation-rail='collapsible'] {
|
||||
width: 6rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* `--material-banner` is the height of a bar pinned across the top of the window — what
|
||||
@@ -241,6 +257,18 @@
|
||||
background-color var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);
|
||||
}
|
||||
|
||||
/* M3's two optional container treatments: "optional vertical divider separates rail from
|
||||
content, placed on the content-adjacent edge" — also its answer to a page scrolling under a
|
||||
fixed rail — and "container fill can be turned off (transparent) as long as items keep ≥3:1
|
||||
contrast". Neither applies to a rail open over a scrim, which is a surface over the page. */
|
||||
[data-navigation-rail][data-divider]:not([data-open]) > [data-navigation-rail-panel] {
|
||||
border-inline-end: 1px solid var(--md-sys-color-outline-variant);
|
||||
}
|
||||
|
||||
[data-navigation-rail][data-fill='false']:not([data-open]) > [data-navigation-rail-panel] {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* Open: expanded over a scrim, in surface-container with a large corner at its inner edge. */
|
||||
[data-navigation-rail][data-open] > [data-navigation-rail-panel] {
|
||||
position: fixed;
|
||||
@@ -627,3 +655,31 @@
|
||||
[data-navigation-rail-header] [data-fab]:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* "Rail transitions from collapsed to expanded should animate the FAB into and out of an extended
|
||||
* FAB" — so the header takes one <x-fab label icon> and morphs it, rather than swapping two by
|
||||
* `display`, which showed the collapsed one at once while the rail's width was still springing.
|
||||
* The label's width springs on the rail's own spatial spring; with the gap closed, what is left is
|
||||
* 16px of padding, the 24px icon and 16px again — the 56px square a collapsed FAB is. The label
|
||||
* stays in the accessibility tree at both widths, so the FAB keeps its name. Unlayered for the
|
||||
* same reason as the rule above: `gap-2` is a utility, and a layer would lose to it. The cap is a
|
||||
* transition needs a length to travel to; a rail FAB's label is a word or two. */
|
||||
[data-navigation-rail-header] [data-fab] > span {
|
||||
max-width: 16rem;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
transition:
|
||||
max-width var(--md-sys-motion-spatial-default-duration) var(--md-sys-motion-spatial-default),
|
||||
opacity var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);
|
||||
|
||||
@variant rail-collapsed {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
[data-navigation-rail-header] [data-fab] {
|
||||
@variant rail-collapsed {
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user