Give a vertical toolbar 24dp and a standard one primary buttons

M3 asks a vertical toolbar for a 24dp margin from the window edge where a
horizontal one keeps 16, and its standard-toolbar colour list ends "Standard
button (Primary)" — the vibrant row of the same list was already honoured, so
the two were being read inconsistently. Both rules are unlayered, because an
icon button's ink is a utility.
Plan: docs/plans/material-3-alignment.md, step 21 (navigation N-12, N-13).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 06:08:13 +02:00
co-authored by Claude Opus 5
parent 789e8b2970
commit 59ca88a0cf
2 changed files with 26 additions and 3 deletions
+21 -2
View File
@@ -7,8 +7,12 @@
* floating a 64px pill in surface-container (or primary-container, `vibrant`) at elevation 3,
* 8px at its ends and 4px between controls; `vertical` stands it on end
*
* Unlayered on purpose: a vibrant toolbar recolours the icon buttons inside it, which draw their
* ink as utilities, and a rule in any layer loses to a utility.
* Placed over the page, a horizontal toolbar keeps 16dp from the window's edge and a vertical one
* 24dp, which is M3's minimum for each.
*
* Unlayered on purpose: a toolbar recolours the icon buttons inside it — primary in a standard
* one, on-primary-container in a vibrant one — and they draw their ink as utilities, which a rule
* in any layer loses to.
*/
[data-toolbar] {
@@ -60,6 +64,13 @@
color: var(--md-sys-color-on-surface);
}
/* M3's colour list for a standard toolbar ends "Standard button (Primary)", as the vibrant list
ends "Standard button (On primary container)" — the row above. An icon button carries its own
ink as a utility, so the container's `color` never reaches it and this rule has to. */
[data-toolbar]:not([data-vibrant]) [data-icon-button]:not([aria-pressed="true"]) {
color: var(--md-sys-color-primary);
}
/* A floating toolbar and its FAB, side by side (or stacked, vertical). */
[data-toolbar-group] {
display: inline-flex;
@@ -95,6 +106,14 @@
translate: 0 -50%;
}
/* "Horizontal toolbars should have a minimum 16dp margin from the edge of the window. Vertical
toolbars should have a minimum 24dp margin"
(docs/reference/m3/components-navigation-selection-inputs.md § Toolbars). */
[data-toolbar][data-vertical][data-toolbar-place="end"],
[data-toolbar-group][data-vertical][data-toolbar-place="end"] {
inset-inline-end: calc(1.5rem + var(--material-safe-right, env(safe-area-inset-right)));
}
[data-toolbar][data-variant="docked"][data-toolbar-place="bottom"] {
inset-inline: 0;
bottom: var(--material-bottom-bar, 0px);
+5 -1
View File
@@ -86,7 +86,11 @@ it('keeps a toolbar at the bottom clear of the navigation bar', function () {
expect($css)
// Never a sum: --material-bottom-bar already swallows the bottom safe area (N-02).
->toContain('bottom: calc(max(var(--material-bottom-bar, 0px), var(--material-safe-bottom, env(safe-area-inset-bottom))) + 1rem);')
->toContain('bottom: var(--material-bottom-bar, 0px);');
->toContain('bottom: var(--material-bottom-bar, 0px);')
// A vertical toolbar keeps 24dp from the edge where a horizontal one keeps 16 (N-12).
->toContain('inset-inline-end: calc(1.5rem + var(--material-safe-right, env(safe-area-inset-right)));')
// A standard toolbar's standard buttons are primary (N-13).
->toContain('[data-toolbar]:not([data-vibrant]) [data-icon-button]:not([aria-pressed="true"]) {');
});
it('offers M3\'s three contrast levels, marking the one in force', function () {