/* * : related buttons in a row, and the shapes a button takes from its place among * its siblings. The connected form is also what `` draws its segments with, which is why * its stylesheet imports this one. A group never wraps: M3's rule, and the press expansion only * reaches a neighbour on the same line anyway. * * Standard (`data-md-button-group="standard"`): the buttons stand apart — 18/12/8/8/8px by size * (ButtonGroupXSmall…XLargeTokens.BetweenSpace) — and pressing a label button widens it and * narrows its neighbours by the same amount, so the row keeps its length: Expressive's press * expansion (ButtonGroupDefaults.ExpandedRatio is 15%; this uses a fixed step per size, 4/6/8/16/ * 20px, on the button's own padding of 16/16/24/48/64px). Icon buttons keep their width. A square * standard group has no inner edges, so it hands its buttons the square corner scale * `` draws (12/12/16/28/28px, 8/8/12/16/16px under the finger), and a * selected button in it turns round. * * Connected (`data-md-button-group="connected"`): 2px apart, the outer corners full, the inner * corners small, smaller still while pressed, and a selected segment (`aria-pressed`, or a checked * input inside it) fully round — ConnectedButtonGroupXSmall…XLargeTokens and the M3 Expressive * connected button group spec: inner corners 4/8/8/16/20px, pressed 2/4/4/12/16px. At the two * smallest sizes a segment is 32px or 40px tall, and M3 names both numbers it must not go below: * "XS and S connected button groups have a 48dp target area and a 48dp minimum width". * * Shape (`data-md-shape="square"`, M3's "Default shape | Round, square" configuration): * `--md-button-group-outer` is what the two ends of a group round to — half the height for a round * group, and for a square one the corner its inner edges take, which is the square table M3 * publishes for connected groups (4/8/8/16/20dp by size). Selection morphs the other way: M3 has a * toggle inside a group "swap shape square/round on selection", so a selected segment in a square * group turns round, which is why the selected rule keeps `--md-button-group-full`. * * "Full" is half the size's height (16/20/28/48/68px), never `--md-sys-shape-corner-full`'s * 9999px. One element mixes full outer corners with small inner ones, and when a box's radii add * up to more than its side, CSS scales every radius by the same factor: a 9999px corner beside an * 8px one shrank the 8px one to a hundredth of a pixel, so the inner corners drew square. * * 's own corner rules carry no specificity, so these reshape the buttons in a group * whatever selector they use; a pressed or selected segment changes one custom property and the * outer corners stay put. */ @layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility; @layer material.components { [data-md-button-group] { --md-button-group-inner: var(--md-sys-shape-corner-sm); --md-button-group-inner-pressed: var(--md-sys-shape-corner-xs); --md-button-group-full: 20px; --md-button-group-square: var(--md-sys-shape-corner-md); --md-button-group-square-pressed: var(--md-sys-shape-corner-sm); --md-button-group-outer: var(--md-button-group-full); --md-button-group-pad: var(--md-sys-measurement-space200); --md-button-group-grow: 6px; display: inline-flex; align-items: center; } [data-md-button-group][data-md-size='xs'] { --md-button-group-inner: var(--md-sys-shape-corner-xs); --md-button-group-inner-pressed: 2px; --md-button-group-full: 16px; --md-button-group-grow: 4px; } [data-md-button-group][data-md-size='md'] { --md-button-group-full: 28px; --md-button-group-square: var(--md-sys-shape-corner-lg); --md-button-group-square-pressed: var(--md-sys-shape-corner-md); --md-button-group-pad: var(--md-sys-measurement-space300); --md-button-group-grow: 8px; } [data-md-button-group][data-md-size='lg'] { --md-button-group-inner: var(--md-sys-shape-corner-lg); --md-button-group-inner-pressed: var(--md-sys-shape-corner-md); --md-button-group-full: 48px; --md-button-group-square: var(--md-sys-shape-corner-xl); --md-button-group-square-pressed: var(--md-sys-shape-corner-lg); --md-button-group-pad: var(--md-sys-measurement-space600); --md-button-group-grow: 16px; } [data-md-button-group][data-md-size='xl'] { --md-button-group-inner: var(--md-sys-shape-corner-lg-increased); --md-button-group-inner-pressed: var(--md-sys-shape-corner-lg); --md-button-group-full: 68px; --md-button-group-square: var(--md-sys-shape-corner-xl); --md-button-group-square-pressed: var(--md-sys-shape-corner-lg); --md-button-group-pad: var(--md-sys-measurement-space800); --md-button-group-grow: 20px; } [data-md-button-group='standard'] { gap: var(--md-sys-measurement-space100); } [data-md-button-group='standard'][data-md-size='xs'] { gap: 18px; } [data-md-button-group='standard'][data-md-size='sm'] { gap: 12px; } /* A square standard group hands its buttons the square corner scale; a selected one rounds. */ [data-md-button-group='standard'][data-md-shape='square'] > * { border-radius: var(--md-button-group-square); } [data-md-button-group='standard'][data-md-shape='square'] > :active:not(:disabled, [aria-disabled='true']) { border-radius: var(--md-button-group-square-pressed); } [data-md-button-group='standard'][data-md-shape='square'] > [aria-pressed='true'] { border-radius: var(--md-button-group-full); } /* Press expansion: the pressed label button grows, the label buttons beside it give way. */ [data-md-button-group='standard'] > :not([data-md-icon-button]):active:not(:disabled, [aria-disabled='true']) { padding-inline: calc(var(--md-button-group-pad) + var(--md-button-group-grow)); } [data-md-button-group='standard'] > :not([data-md-icon-button]):has(+ :not([data-md-icon-button]):active:not(:disabled, [aria-disabled='true'])) { padding-inline-end: calc(var(--md-button-group-pad) - var(--md-button-group-grow)); } [data-md-button-group='standard'] > :not([data-md-icon-button]):active:not(:disabled, [aria-disabled='true']) + :not([data-md-icon-button]) { padding-inline-start: calc(var(--md-button-group-pad) - var(--md-button-group-grow)); } /* A square group's ends take the corner its inner edges take. */ [data-md-button-group][data-md-shape='square'] { --md-button-group-outer: var(--md-button-group-inner); } [data-md-button-group='connected'] { gap: var(--md-sys-measurement-space25); } [data-md-button-group='connected']:is([data-md-size='xs'], [data-md-size='sm']) > * { min-inline-size: var(--md-sys-measurement-space600); } [data-md-button-group='connected'] > * { --md-button-group-corner: var(--md-button-group-inner); border-start-start-radius: var(--md-button-group-corner); border-end-start-radius: var(--md-button-group-corner); border-start-end-radius: var(--md-button-group-corner); border-end-end-radius: var(--md-button-group-corner); } [data-md-button-group='connected'] > :active { --md-button-group-corner: var(--md-button-group-inner-pressed); } [data-md-button-group='connected'] > :is([aria-pressed='true'], :has(:checked)) { --md-button-group-corner: var(--md-button-group-full); } [data-md-button-group='connected'] > :first-child { border-start-start-radius: var(--md-button-group-outer); border-end-start-radius: var(--md-button-group-outer); } [data-md-button-group='connected'] > :last-child { border-start-end-radius: var(--md-button-group-outer); border-end-end-radius: var(--md-button-group-outer); } }