# Material Design 3 — Styles Supplement (Spacing; Color additions; Motion transition patterns) Extraction from sitemap pages `reference-styles.md` did not cover (fetched directly, not via in-site navigation). Same structure as the reference. Only material **not** already in `reference-styles.md` is included; where a fetched page turned out to be a duplicate of an already-covered page, that is noted instead of repeating it. **Duplicate pages found (no new content beyond what's already in the reference):** - `styles/color/system/overview` — byte-identical to `styles/color/system` (already in the reference's Color section / Source URLs), *except* it also carries a Resources table not previously captured — see Color § Values below. - `styles/color/advanced/overview` — byte-identical to `styles/color/advanced` (already in the reference's Color § Source URLs; its linked sub-pages apply-colors/define-new-colors/adjust-existing-colors are already the basis of the reference's "Advanced customization best practices" rules). - `styles/color/dynamic/choosing-a-source` — byte-identical to `styles/color/dynamic` (already in the reference's Color § Source URLs), *except* it's the canonical location for the source-selection decision criteria — see Color § Dynamic sources below (the reference didn't extract these criteria). - `styles/motion/easing-and-duration/applying-easing-and-duration` — its "Suggested easing and duration pairs" table, "Choosing an easing set", "Choosing an easing type" (by transition direction), and "Choosing a duration" (by size / enter vs. exit) sections are already reproduced verbatim in the reference's Motion § Rules and § Values. The only new fact is an M2-vs-M3 style comparison — see Motion § Principles below. --- ## Spacing Absent from `reference-styles.md` entirely — no Spacing section existed. This is a full addition. ### Principles - Spacing is applied to the margins, padding, and gaps of a component, UI element, or layout. - Spacing adapts to different values based on context, like mobile vs. desktop, or density settings. - The spacing system is measured on an **8dp scale**, where **space100 = 8dp**. - Spacing is applied to the flow of elements (horizontal, vertical) or in relation to elements (leading, trailing, top, bottom, gap). - Unlike the color system (which adjusts light/dark theme logic across all components at once), spacing logic is tailored and built within each component individually — there's no single global spacing transform. - Components have padding/margin/gap tokens that map to system spacing tokens, which resolve to final dp values (component token → system token → value). ### Rules (Google's wording) - Spacing has three categories: **padding** (space inside an element), **gap** (space between elements in a grid or container), and **margin** (space outside an element). Position can be vertical, top, bottom, horizontal, leading, or trailing. **Leading**/**trailing** swap sides in RTL languages. - **Do** define padding and gaps on the parent container to organize all elements inside. - **Don't** define margins on child elements — they usually aren't uniform and require more tokens. - **Use padding & gaps before using margins**: Material rarely uses margins in components; padding/gaps apply spacing more uniformly. Only use margins for spacing beyond the parent container's padding, or in layouts. - Use a horizontal/vertical gap for simple components where gaps are always the same size; complex components with many different gaps should name them by the elements on each side (e.g. "icon-label gap") rather than a single generic gap token. - When text is scaled up to 200%, the same spacing should be preserved by default (spacing does not scale with text). - What to use, in priority order: 1. **Pre-tokenized components** — some Material components map to spacing system tokens out of the box (work is ongoing to hook up all components; this mapping can be customized for form factor/density). 2. **System tokens** — apply these to custom components/layouts, replacing hardcoded values. 3. If the right system token doesn't exist, **customize the system** (see below) and add your own. - Customizing the system (three approaches, by scope): - **Customize Material's existing component spacing** — remap a component attribute to a different system token product-wide (e.g. change "button top padding" from **space125** to **space200** for a taller default button). - **Add custom system spacing & patterns** — when you need units beyond what Material provides, or have a recurring adaptive pattern. Follow the multiplier convention for new tokens (e.g. **space225 = 18dp** = 8dp × 2.25). Product-specific recurring patterns can get their own pattern token (e.g. if cards and sheets always adapt horizontal content padding the same way, create a **surface-content padding horizontal** token for that pattern). - **Add adaptive layout & density** — map the same component to different system tokens per device type (mobile vs. desktop), and/or adapt vertical padding to different values per density setting, while keeping the same core component. - **Note:** system spacing tokens are currently only used on **Jetpack Compose** (see Availability below) — this is a stronger platform restriction than color/elevation/shape, which have broader (if uneven) support. ### Values #### Availability | Type | Resource | Status | | --- | --- | --- | | Implementation | Android Views (MDC-Android) | Unavailable | | Implementation | Jetpack Compose | Available | | Implementation | Web | Unavailable | #### Spacing scale The site does not render the token→dp table as text (it's an image diagram); the following is reconstructed from the images' alt-text and from dp values cited inline elsewhere on the page, and should be treated as inferred, not a verbatim site table: | Token | Multiplier | Value | | --- | --- | --- | | space25 | 0.25× | 2dp | | space50 | 0.5× | 4dp | | space75 | 0.75× | 6dp | | **space100** | **1×** | **8dp (base unit, `md.sys.measurement.space100`)** | | space125 | 1.25× | 10dp | | space200 | 2× | 16dp | | space300 | 3× | 24dp | | space400 | 4× | 32dp | | space500 | 5× | 40dp | | space600 | 6× | 48dp | | space700 | 7× | 56dp | | space800 | 8× | 64dp | | space900 | 9× | 72dp | Basis for this reconstruction: the overview page's scale diagram alt-text reads "a spacing scale shows 2, 4, 6, and 8 at the bottom range and 48, 56, 64, and 72 at the top of the range"; the tokens page states the main range "covers 0x to 9x" of the 8dp base unit and separately defines nested sub-1x units at "0.25x, 0.5x, 0.75x, 1.25x"; the overview page separately lists the same nested dp values ("2dp, 4dp, 6dp, and 10dp"). Values beyond space900 (e.g. the 18dp/space225 example) are explicitly presented as **custom**, not part of the default set. Material only defines the nested/nonstandard units it actively uses — the scale is not a complete arithmetic progression at every step. #### Component spacing — naming convention | | Going forward | Legacy | | --- | --- | --- | | Prefix | `padding`, `margin`, `gap` | `space` | | Positional modifiers | horizontal, vertical, leading, trailing, top, bottom | leading-space, trailing-space, top-space, bottom-space, between-space | | Example | "Medium button: leading padding" | "Medium button: leading space" | #### Parts of spacing — example (Search) The search container: 8dp vertical padding, 8dp horizontal gaps, 24dp horizontal margins by default (narrows to 12dp when focused, while padding/gaps stay the same). The 24dp default margin exists specifically "to ensure accurate placement from the screen edge." #### Spacing concepts diagrammed on the site (numbered image captions — anatomy, not values) - Component layout: (1) vertical padding top & bottom, (2) vertical gap, (3) horizontal padding leading & trailing, (4) horizontal gap. - Page layout: (1) margin, (2) top padding, (3) horizontal padding leading & trailing, (4) spacer/gap, (5) vertical gap. Layouts additionally use **panes** (layout containers, which can be fixed, flexible, floating, or semi-permanent) and **spacers** (space between two panes; contains a drag handle if the panes are resizable). ### M3 vs M3 Expressive differences No Expressive-specific spacing changes are called out on these pages (unlike shape/motion/typography, spacing carries no "M3 Expressive" labelled update section). The system is presented as a single, version-agnostic linear scale. ### Accessibility - Spacing must be preserved (not scaled) when text is scaled up to 200%, so layouts stay stable and legible as text grows — spacing is a support mechanism for text-resizing accessibility, not something that competes with it. ### Source URLs - https://m3.material.io/styles/spacing/overview - https://m3.material.io/styles/spacing/applying-spacing - https://m3.material.io/styles/spacing/tokens --- ## Color — additions ### Static: Custom brand color scheme Not previously fetched. Supplements the reference's Color section (which covers baseline/static generally but not the brand-specific workflow). **Principles** - A **brand-based static scheme** is hand-picked by the product team to align with the product's brand color(s), as opposed to the **baseline** static scheme (Material's own default) or a **dynamic** scheme. It requires greater ongoing investment since the team creates and maintains it entirely. - End-users see: an accessible UI with static colors, and "a product that looks like its brand." **Rules (Google's wording)** - Brand schemes are still generated through the same tonal-palette machinery as dynamic color: you can set a **custom source color independently for each of the 6 palette groups** — Primary, Secondary, Tertiary, Error, Neutral, and Neutral Variant — not just Primary. Setting only Primary and leaving the rest defaulted is also valid ("use the scheme as-is"). - Workflow (Material Theme Builder Figma plugin): add a new theme, name it (the name becomes the color role prefix in Figma), set a custom Hex source color for Primary (and optionally Secondary/Tertiary/ Error/Neutral/Neutral Variant) → generates a full custom color scheme with the same role set as baseline. - Enabling "Generate State Layers" in the plugin settings when creating the theme is called out as necessary groundwork for interaction-state design (cross-references state layers). - Point of escalation: "want to further adjust your brand color scheme?" and "need to make adjustments?" both route to **Advanced customizations** (apply/define/adjust colors) — i.e. custom-brand is the starting point, advanced customization is the refinement path. - Develop: export the branded scheme from Material Theme Builder for Jetpack Compose, Android Views, Flutter, Web, or as a JSON file. **Source URLs** - https://m3.material.io/styles/color/static/custom-brand ### Dynamic: choosing and using a source Two new sub-pages (content-based-source, user-generated-source) plus decision criteria from choosing-a-source that the reference's Color section states only as a single pipeline description, not as selection criteria. **Principles** - Both user-generated and content-based color go through the same pipeline: the image is digitally analyzed through **quantization**, a single color is selected as the source color, and tones are chosen and assigned to each color role (this is the concrete mechanism behind the "dynamic color pipeline" already summarized in the reference). - **User-generated color**: sourced from the user's wallpaper. - **Content-based color**: sourced from in-app content — an album thumbnail, a logo, a video preview. **Rules (Google's wording) — decision criteria (not previously captured)** | Source type | Choose it if… | | --- | --- | | User-generated | Users would benefit from a personalized experience that's well-tested; you want to showcase the latest Material features | | Content-based | Content is front-and-center in the product; the team can do some advanced customization; it supports usability of content-centric features like media players; best applied to contained screen elements adjacent to the source image (the source image itself need not stay visible) | | Multiple sources | Product requirements meet more than one of the above criteria and the team doesn't mind extra customization work; get started with user-generated color first, then customize | - Example of multiple sources coexisting: a photo app derives content-based color (green) for edit buttons from the in-app photo, while wallpaper-derived user-generated color (red) drives share buttons elsewhere in the same screen. - Content-based color guidance: apply it where it enhances brand identity and personalization (e.g. a music app deriving color from album artwork; a news app differentiating publications by their content color). - QA/testing step for user-generated color (Figma workflow): use the Material Theme Builder's "Dynamic" mode, add a real image or use the Shuffle icon for a random source color, swap it onto frames, and **repeat across a range of colors** to get a sense of how the product will appear across different users' devices/wallpapers — i.e. dynamic-color design review should be done across many source colors, not just one or two. - Android implementation reference specifically for content-based color: MDC-Android's "Content-based dynamic color" doc (separate from the general dynamic-color doc already cited). **Source URLs** - https://m3.material.io/styles/color/dynamic/choosing-a-source - https://m3.material.io/styles/color/dynamic/content-based-source - https://m3.material.io/styles/color/dynamic/user-generated-source --- ## Motion — Transitions (supplement) The reference's Motion section already reproduces the easing/duration Rules and Values from `applying-easing-and-duration` verbatim, and names the six transition patterns in one summary line without detail. This section supplies the missing detail: what each pattern is for, what it's commonly used with, platform (Android/iOS) differences, and the accessibility/consistency criteria for transitions overall — which also fills the gap the reference explicitly flagged ("No general reduced-motion policy was found stated on `styles/motion` itself"). **Naming note:** the current M3 site does **not** use the older M2 terms "shared axis / fade through / fade." The current (2026) taxonomy is: **Container transform**, **Forward and backward** (≈ old shared axis), **Lateral**, **Top level** (≈ old fade through), **Enter and exit** (subsumes old "fade" cases), and **Skeleton loaders** (new, not an M2 concept). Anyone looking for "shared axis"/"fade through"/"fade" by name should map to this table. ### Principles — what makes a good transition - **Follows accessibility settings**: when a platform's reduced-motion setting is on, transitions should use subtle fades instead of intense sliding/scaling, and disable decorative effects like parallax or shape morphing. *(This is the missing general reduced-motion policy for `styles/motion` — previously only found at the component level, e.g. carousel/menus.)* - **Consistent**: applying the same transition type consistently for the same kind of navigation makes apps feel cohesive and predictable (e.g. multiple Android apps sharing one forward/backward transition). - **Stable layouts**: use skeleton loaders (subtle pulsing) so content doesn't shift position or pop in abruptly as it loads. - **No jarring jump cuts**: avoid instant, uncued transitions by default — they're disorienting. Exception: a jump cut may be preferred when pure efficiency is the top priority (e.g. opening a menu in a productivity app). - **Coherent spatial model**: transitions should help users understand an app's physical/spatial layout (e.g. keep a consistent axis when moving between collapsed/expanded carousel views; don't flip between horizontal and vertical layouts). - **Unified direction**: elements are grouped and move along one primary axis rather than independently; only genuinely persistent elements (e.g. a hero image) should remain visible throughout — animating many persistent elements independently is distracting. - **Clean fades**: fully fade out old content before fading in new content; avoid overlapping partially-transparent frames. If a cross-fade is unavoidable, keep it quick and hide it during the fastest part of the transition (e.g. a dialog entering mid-screen should not slowly fade on top of content — use a short fade to hide the overlap). - **Simple style**: transitions are frequent and utility-driven, not a showcase for stylized motion — avoid overt effects like bouncy springs on common transitions. ### Rules — per-pattern guidance (Google's wording) | Pattern | Use for | Commonly used with | Do / Don't / Caution | | --- | --- | --- | --- | | **Container transform** | Seamlessly transforming an element to show more detail (e.g. a card expanding into a details page); hero moments that should be expressive; shallow hierarchies (expand for detail, then collapse); creating a seamless connection between elements. Most dramatic/expressive pattern — reserve for the right context. | Cards, lists, image galleries, search boxes, sheets, FABs, chips | **Do** use it for hero moments instead of a forward/backward transition. **Don't** use it in apps with deep hierarchies (motion becomes excessive) or in utility-focused navigation (style mismatch). | | **Forward and backward** | Navigating between screens at consecutive hierarchy levels (e.g. inbox → message thread) | Lists, cards, buttons, links | **Do** use platform defaults — easy to implement, stays current with platform updates. Android fades content as screens slide (reduces motion vs. a full-width slide); iOS uses parallax (background slides slower than foreground). **Caution**: container transform requires custom implementation and can feel excessive if overused for this role. | | **Lateral** | Navigating between peer content at the same hierarchy level (e.g. swiping tabs in a content library) | Tabs, carousels, image galleries | Elements are grouped and slide in unison with **no fade or parallax**, creating a strong peer relationship and hinting at swipe-ability. **Caution**: fading content while it slides weakens the peer/swipe cue and can be confused with forward/backward. **Don't** use for hierarchical navigation — full-width sliding is excessive and wrongly implies a peer (non-hierarchical) relationship. | | **Top level** | Navigating between top-level destinations (e.g. tapping a nav bar/rail/drawer item) | Navigation bar, navigation rail, navigation drawer | Exiting screen quickly fades out, then the entering screen fades in — intentionally **no** grouping or persistent elements, since top-level destinations aren't necessarily related. **Don't** use a lateral transition here — it wrongly implies you can swipe between top-level destinations, conflicting with carousel/list swipe gestures. | | **Enter and exit — within screen bounds** | Introducing/removing a component in the context of the main UI (modal, e.g. a dialog; or non-modal, e.g. a bottom sheet coexisting with content) | FABs, dialogs, menus, snackbars, time pickers, tooltips | Android: expand/collapse along x or y axis only (scale and z-axis motion are avoided — they'd imply an elevation change, which conflicts with M3's reduced-elevation model). iOS: uniform scale to enter, fade to exit. Enter direction is informed by on-screen location, expanding away from the device edge (e.g. a top menu expands downward; a bottom snackbar expands upward). **Don't** use this pattern for navigating hierarchical screens — full-height sliding is excessive and creates an unclear screen-to-screen relationship. | | **Enter and exit — beyond screen bounds** | Components that slide fully on/off screen | App bars, banners, navigation bar, navigation rail, navigation drawer, sheets | Android: expand/collapse along x or y axis while sliding on/off (adds shape emphasis). iOS: slides on/off without changing shape. Coplanar side sheets shrink the available content area rather than overlaying it. Can be scroll-driven (e.g. a top app bar or nav bar sliding off/on during scroll, to reclaim screen space). Entry/exit location establishes spatial memory: notifications enter from the top (matches the pull-down drawer), a nav drawer enters from the left (matches its off-screen position), a bottom sheet/keyboard enters from the bottom (easiest to reach). | | **Skeleton loaders** | Transitioning from a temporary loading state to the fully loaded UI | Used in combination with other transition patterns | Subtle pulsing animation indicates indeterminate progress, animating from top-left to bottom-right. Once content loads, it quickly fades in **on top of** the skeleton loader (not instantly popping in). | ### Values Durations and easing for these patterns are governed by the already-referenced tables (Suggested easing/duration pairs; legacy duration tokens) — no separate duration table is given per pattern on these pages. The pattern choice itself is the "value" documented here; see the Rules table above for the authoritative per-pattern mapping (this *is* the durations/patterns cross-reference the task asked for — the site does not tie a specific numeric duration to "container transform" etc. beyond the general begin/end-on-screen vs. enter vs. exit rules already in the reference). ### M2 vs M3 easing note (from `applying-easing-and-duration`; not an M3-vs-Expressive distinction) - Compared to M2's more utilitarian easing style, **M3 easing is more expressive**: transitions have "snappy take-offs and very soft landings." - **M3 durations are slightly longer than M2's**, deliberately, to give transitions time to come to a gentle rest without feeling abrupt. ### Accessibility requirements - General reduced-motion policy for transitions (see Principles above): substitute subtle fades for intense sliding/scaling, and disable decorative effects (parallax, shape morphing) when a platform's reduced-motion setting is on. This generalizes — and predates in priority — the component-level reduced-motion notes already in the reference (carousel, menus). ### Source URLs - https://m3.material.io/styles/motion/transitions/applying-transitions - https://m3.material.io/styles/motion/transitions/transition-patterns - https://m3.material.io/styles/motion/easing-and-duration/applying-easing-and-duration (mostly duplicate of already-referenced content; see M2-vs-M3 note above for the one new fact)