/* * M3 Expressive's toolbars (DockedToolbarTokens, FloatingToolbarTokens, androidx Compose Material 3, * Apache-2.0). * * docked a 64px bar across the bottom of the screen in surface-container, square, its * controls spread out 4 to 32px apart between 16px ends; with a FAB, the controls * at the start and the FAB flat at the end * 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 * * 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. * * On web and large screens a docked toolbar "can be rounded", and dividers can organise its * controls into groups (docs/reference/m3/components-navigation-selection-inputs.md § Toolbars): * `rounded` does the first from `expanded`, and a divider in the slot the second at any width. * * 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] { display: flex; align-items: center; gap: 0.25rem; } [data-toolbar][data-variant="docked"] { width: 100%; min-height: calc(4rem + var(--material-safe-bottom, env(safe-area-inset-bottom))); justify-content: center; column-gap: clamp(0.25rem, 4vw, 2rem); padding-inline: 1rem; padding-bottom: var(--material-safe-bottom, env(safe-area-inset-bottom)); background-color: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface-variant); } [data-toolbar][data-variant="floating"] { display: inline-flex; height: 4rem; padding-inline: 0.5rem; border-radius: var(--md-sys-shape-corner-full); background-color: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface-variant); box-shadow: var(--md-sys-elevation-3); } [data-toolbar][data-variant="floating"][data-vertical] { width: 4rem; height: auto; flex-direction: column; padding-block: 0.5rem; padding-inline: 0; } [data-toolbar][data-vibrant] { background-color: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); } [data-toolbar][data-vibrant] [data-icon-button]:not([aria-pressed="true"]) { color: var(--md-sys-color-on-primary-container); } [data-toolbar][data-vibrant] [data-icon-button][aria-pressed="true"] { background-color: var(--md-sys-color-surface-container); 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 docked toolbar with a FAB: the controls at the start, the FAB at the end, resting on the bar at elevation 0 — M3 puts a FAB nested in another component there, and Compose's FloatingActionButtonDefaults.bottomAppBarFabElevation() is 0 in every state. `` draws its shadow with utilities, which is one more reason this file is unlayered. */ [data-toolbar][data-variant="docked"]:has(> [data-toolbar-fab]) { justify-content: flex-start; } [data-toolbar-fab] { display: flex; margin-inline-start: auto; } [data-toolbar-fab] [data-fab], [data-toolbar-fab] [data-fab]:hover { box-shadow: none; } /* Groups of controls, a divider between each two (``, or `` in a vertical toolbar). The divider draws itself stretched across its row, which in a toolbar would run it into the container's edges; here it stands as long as the 40px icon buttons it separates, centred on them, as the large-screen docked toolbar in M3's guidelines draws it (toolbars/guidelines § Adaptive design → Resizing). The divider is `self-stretch`, a utility, which this unlayered rule beats. */ [data-toolbar]:not([data-vertical]) > [role="separator"][aria-orientation="vertical"] { align-self: center; height: 2.5rem; } [data-toolbar][data-vertical] > [role="separator"][aria-orientation="horizontal"] { align-self: center; width: 2.5rem; } /* A floating toolbar and its FAB, side by side (or stacked, vertical). */ [data-toolbar-group] { display: inline-flex; align-items: center; gap: 0.5rem; } [data-toolbar-group][data-vertical] { flex-direction: column; } /* Placed over the page: centred above the bottom edge, or centred against the end edge. * * A toolbar at the bottom shares the screen region with a navigation bar, so it clears the one * publishes as --material-bottom-bar, exactly as the FAB and the snackbar do — * `max()`, not a sum, because that height already swallows the bottom safe area; without a bar * the safe area alone applies. A *docked* toolbar and a navigation bar must never be on screen * together at all (docs/reference/m3/components-navigation-selection-inputs.md § Toolbars); the * offset is the backstop, not a licence. */ [data-toolbar-place="bottom"] { position: fixed; bottom: calc(max(var(--material-bottom-bar, 0px), var(--material-safe-bottom, env(safe-area-inset-bottom))) + 1rem); left: 50%; z-index: 30; translate: -50% 0; } [data-toolbar-place="end"] { position: fixed; top: 50%; inset-inline-end: calc(1rem + var(--material-safe-right, env(safe-area-inset-right))); z-index: 30; 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); left: 0; translate: none; } /* The large-screen docked toolbar: from `expanded` (840px) fully rounded, like the one M3 shows on the web, and spanning what it is written in. At the bottom of the window it lifts off the edges — 16dp from each side, M3's minimum outside padding for a toolbar, and 16px above the bottom bar or the safe area, as a floating toolbar sits — so the curve never meets the window's frame, and the bottom safe area, which it no longer touches, stops padding it. Below `expanded` it is the square, full-width docked toolbar M3 requires ("Avoid applying rounded corners to the container"). */ @media (width >= 52.5rem) { [data-toolbar][data-variant="docked"][data-rounded] { min-height: 4rem; padding-bottom: 0; border-radius: var(--md-sys-shape-corner-full); } [data-toolbar][data-variant="docked"][data-rounded][data-toolbar-place="bottom"] { right: calc(1rem + var(--material-safe-right, env(safe-area-inset-right))); bottom: calc(max(var(--material-bottom-bar, 0px), var(--material-safe-bottom, env(safe-area-inset-bottom))) + 1rem); left: calc(1rem + var(--material-safe-left, env(safe-area-inset-left))); width: auto; } }