# Sass API

> Configure Sass builds and use the shared functions and mixins.

## Setup and configuration

Use the package importer to resolve the public Sass entry. Compile `app.scss` with `sass --pkg-importer=node app.scss app.css`.

```
@use "pkg:@expressivecss/expressive/scss" as expressive with (
  $md-source: #6750a4,
  $expressive-include-fonts: false
);

.notice {
  @include expressive.typescale("body-large");
  @include expressive.bp-up("expanded") { padding: 2rem; }
}
```

The main entry emits the stylesheet and forwards the shared abstracts. To use only functions and mixins without emitting framework CSS, load `pkg:@expressivecss/expressive/scss/abstracts/index`. Those mixins still need the framework tokens in the consuming stylesheet. Sass modules load once; configure a module on its first load.

Use `pkg:@expressivecss/expressive/scss/custom` to select `$components` and `$utilities`. Each is an ordered list of partial names. `null` loads the full group; `()` loads none. Tokens and base styles always load. Follow the [smaller-build recipes](/index.html.md#smaller-builds) for supporting partials.

| Configuration | Default and purpose |
| --- | --- |
| `$md-source` | `#c6a0f6`, the theme seed. Runtime theming uses `--md-source`. |
| `$expressive-include-fonts`, `$expressive-font-path` | `true` and `"../fonts"`. Disable bundled font faces when supplying your own; otherwise keep the font files at the emitted URLs. |
| `$expressive-glass`, `$expressive-glass-blur`, `$expressive-glass-opacity` | `false`, `16px` and `72%`. Opacity must be a percentage. See [Frosted glass](/glass.html.md) for runtime switches. |
| `$gutter-width`, `$element-top-margin`, `$element-bottom-margin` | `1.5rem`, one third of the gutter and two thirds of the gutter. Shared layout spacing. |
| `$root-font-size`, `$font-stack`, `$text-color`, `$link-color` | `16px`, the plain/fallback typeface tokens, `on-surface` and `primary`. Prefer [runtime tokens](/tokens.html.md) for theme-dependent values. |
| `$flow-text-min`, `$flow-text-max`, `$flow-text-from`, `$flow-text-to` | `1.2rem`, `1.68rem`, `360px` and `960px`. Fluid type size and viewport bounds. |
| `$menu-item-height` | `50px`, the base used to size autocomplete image thumbnails at 10px less. |
| `$breakpoints`, `$sys-color-roles` | Configurable maps for responsive boundaries and color role generation. Changing their keys affects the classes and tokens emitted by the build. |
| `$elevations`, `$button-sizes`, `$icon-button-sizes`, `$button-toggle-colors` | Readable shared maps, without `!default`; they cannot be configured through `@use ... with`. Size maps have `xsmall`, `small`, `medium`, `large` and `xlarge` entries. The toggle map holds a (container, label) color pair per button style for `false` and `true` pressed states. |
| `$icon`, `$icon-label`, `$trend-arrow`, `$caret-down`, `$expand-more` | Shared icon selectors and SVG image values. Changing them affects generated controls as well as authored markup. |

Names beginning with `_` or `-` are Sass-private. The forwarded `$expressive-disabled` selector is a shared implementation value, not a configurable `!default` setting. `$motion-fast-spatial` is a compatibility easing value; prefer the spring functions or motion tokens for new styles.

## Functions

| Function | Arguments and result |
| --- | --- |
| `rem($px)` | Converts a pixel length to rem using a 16px base. `rem(24px)` returns `1.5rem`. |
| `breakpoint($name)` | Returns the named lower boundary: `compact` 0px, `medium` 600px, `expanded` 840px, `large` 1200px or `extra-large` 1600px. Unknown names fail compilation. |
| `state-opacity($state)` | Returns the token opacity as a CSS percentage calculation. Accepts `hover`, `focus`, `pressed` or `dragged`; unknown states fail compilation. |
| `state-layer($color, $state, $base: transparent)` | Returns an OKLab `color-mix()` of the state color over the base, using that state's opacity token. |
| `spring($damping, $stiffness)` | Returns a sampled CSS `linear()` easing. The arguments are damping ratio and stiffness. Pair it with the matching duration. |
| `spring-duration($damping, $stiffness)` | Returns the settling time in seconds for the same spring. Use positive stiffness and the damping values shown in [Transitions](/css-transitions.html.md#springs). |

## General mixins

Call mixins with `@include expressive.name(...)` inside a selector unless the entry says otherwise.

| Mixin | Output |
| --- | --- |
| `bp-up($name)`, `bp-down($name)`, `bp-between($from, $to)` | Wrap a content block in a media query. Lower bounds are inclusive; upper bounds are exclusive. |
| `z-depth($level, $important: false)` | Sets a token-based shadow. Levels are `0`, `1`, `1-half`, `2`, `3`, `4`, `5`. Unknown levels fail compilation. |
| `typescale($role, $emphasized: false)` | Sets font family, size, weight, line height and letter spacing from the named type role. See [Typography](/typography.html.md) for all 15 roles. |
| `icon-size($size, $line-height: $size)` | Sets an icon glyph's font size, width, height and line height. Pass `1` as the line height for a glyph on a text baseline. |
| `visually-hidden($important: false)` | Clips content visually while retaining it for assistive technology and keyboard focus. |
| `focus-ring($offset: 2px)` | Draws a 3px secondary-color outline on the selector where included, 2px outside it by default. A negative offset draws it inside. |
| `focus-visible($offset: 2px)` | Draws the focus ring inside a nested `&:focus-visible` selector. |
| `list-reset()` | Removes a list's markers, margin and padding. |
| `ellipsis()` | Keeps text on one line and cuts it off with an ellipsis. |
| `fill-parent()` | Positions the element absolutely over its whole positioned parent. |
| `print-hidden()` | Hides the element when printing, with `!important` so no display rule brings it back. |
| `forced-colors-selected()` | Adds an inset Highlight outline in forced-colors mode so selection remains visible. |
| `forced-colors-fill($color: CanvasText)` | Preserves a drawn shape with a system background color in forced-colors mode. Use on an indicator or mask, not a whole content region. |
| `state-layer-ring($outer, $inner, $color, $state)` | Draws a state-layer box-shadow between the outer and inner control sizes. |
| `glass($color)` | Adds the optional translucent container and backdrop blur behind the glass style query. Pass the solid background color. Reduced transparency or increased contrast restores it. |

```
.notice {
  @include expressive.z-depth("1");
  @include expressive.focus-visible();
  &:hover {
    background: expressive.state-layer(var(--md-sys-color-primary), "hover");
  }
  @include expressive.bp-between("medium", "large") { padding: 1rem; }
}
```

## Component mixins

These lower-level mixins build framework components. Prefer the documented HTML and classes for application code. A mixin emits styles only; it does not add semantics, keyboard behavior or labels. `choice-fieldset`, `nav-destination` and `nav-destination-row` are available through the abstracts entry only; the main and custom entries hide them.

| Mixin | Contract |
| --- | --- |
| `btn($height, $border-radius, $padding-left, $padding-right, $font-size)` | Button geometry and base interaction styles. Every argument is optional and defaults to small-button tokens, with 40px-equivalent height, full corners, 16px side insets and label-large type. |
| `btn-filled()`, `btn-tonal()`, `btn-elevated()`, `btn-outlined()`, `btn-flat()` | Button colors, elevation, state tints and focus styles. Combine one with `btn()`. Flat corresponds to the text style. |
| `btn-disabled()` | Disabled colors and pointer behavior. Native `disabled` or equivalent application behavior must enforce keyboard inactivity. |
| `button-size($name)`, `icon-button-size($name)` | Emit size custom properties from their corresponding size map. They do not emit type styles. |
| `btn-states($on, $base, $hover-depth: null, $press-depth: null)` | Hover and focus state tints of `$on` over `$base`, plus the focus ring. The optional depths are `z-depth()` levels for hover and press. |
| `header-bar($gap)`, `header-bar-headline()` | The 64px-minimum header row of a full-screen dialog, side sheet or pane, with no fill or shadow, and its title-large heading that takes the free space. The caller sets the padding. |
| `text-action($selected: null, $container, $on-container)` | Hover and selected states for a text item without button chrome. `$selected` is a selector suffix such as `'[aria-current="page"]'`; the selected item takes the secondary-container colors unless others are passed, plus a forced-colors outline. |
| `header-icon-action()` | A 48px circular header action with a 24px-equivalent icon, hover tint and visible focus. |
| `card-media-trigger()` | An absolutely positioned trigger covering card media, including state and focus styling. Use a positioned container and a named native control. |
| `trend-arrow()`, `tree-chevron()` | Pseudo-element masks for an up-trend arrow or a closed tree branch. The consuming component rotates them for other states and RTL. |
| `choice-fieldset($radius, $control)` | A wrapping fieldset of labelled choices. Pass the label radius and control selector used for focus and disabled states. |
| `selection-control($width, $height, $border-color)` | Clears a checkbox, radio or switch input's native look to a box of the given size with a 2px border, so the control can be painted on the input. |
| `selection-control-states($outer, $inner, $checked: ":checked")` | Hover, checked hover and focus state-layer rings from the inner size out to the outer size. `$checked` lists the states whose ring is primary. |
| `selection-control-label($display: flex)` | A 48px minimum label row for a checkbox, radio or switch, with body-large type and a 12px gap. |
| `nav-destination($prefix, $inset, $transition)` | Stacked navigation destination styles. The prefix names component tokens, such as `nav-bar`; inset is top padding and transition is a CSS transition value. Accepts an optional content block. |
| `nav-destination-row($prefix)` | Changes the stacked destination to a horizontal row. Include after the stacked styles. |
| `chart($name, $colors: 4, $on-colors: false, $grid: true, $round: false, $rows: false, $tooltip: top, $cursor: null, $lines: false, $legend-columns: null)` | At stylesheet top level, emits a chart's common container, plot, tooltip, labels, legend and tokens, with the supplied class prefix. The options add 5 or 6 series colors and their on-colors, drop the grid, draw a round or row-band plot, centre the tooltip, draw a `line` or `band` cursor, style SVG lines, and lay the legend out as a table of 3 or more columns. |
| `chart-axis($name, $beside: true)` | At stylesheet top level, emits value labels and grid lines for the named chart. `false` leaves label spacing to the component. |
| `chart-column-motion()` | Inside a column/bar container, animates marks from the zero line or previous values when reduced motion is not requested. |

## Partial directory

Each component and utility partial links to its usage guide below. For the custom entry's lists, remove `components/` or `utilities/`. For example, use `"menu"` in `$components` and `"spacing"` in `$utilities`. `"forms"` includes the complete forms group; a path such as `"forms/checkboxes"` selects one forms partial.

This alphabetical directory is a lookup table, not load order. Preserve the component index's order, with icons first, and include supporting partials. The [recipes](/index.html.md#smaller-builds) show working combinations. Base and token partials always load with either public stylesheet entry.

| Partial | Usage guide |
| --- | --- |
| `base/fonts` | [Typography](/typography.html.md) |
| `base/global` | [Getting started](/index.html.md) |
| `base/grid` | [Grid](/grid.html.md) |
| `base/normalize` | [Getting started](/index.html.md) |
| `base/print` | [Helpers](/helpers.html.md) |
| `base/prose` | [Typography](/typography.html.md) |
| `base/typography` | [Typography](/typography.html.md) |
| `components/accordion` | [Accordion](/accordion.html.md) |
| `components/alert` | [Alert](/alert.html.md) |
| `components/aura` | [Aura](/aura.html.md) |
| `components/avatar` | [Avatar](/avatar.html.md) |
| `components/back-to-top` | [Back to top](/back-to-top.html.md) |
| `components/badges` | [Badges](/badges.html.md) |
| `components/bar-chart` | [Bar chart](/bar-chart.html.md) |
| `components/bottom-sheet` | [Bottom sheet](/bottom-sheet.html.md) |
| `components/breadcrumb` | [Breadcrumbs](/breadcrumbs.html.md) |
| `components/button-groups` | [Button groups](/button-groups.html.md) |
| `components/buttons` | [Buttons](/buttons.html.md) |
| `components/calendar` | [Calendar](/calendar.html.md) |
| `components/cards` | [Cards](/cards.html.md) |
| `components/carousel` | [Carousel](/carousel.html.md) |
| `components/cascader` | [Cascader](/cascader.html.md) |
| `components/chips` | [Chips](/chips.html.md) |
| `components/column-chart` | [Column chart](/column-chart.html.md) |
| `components/command-palette` | [Command palette](/command-palette.html.md) |
| `components/confetti` | [Confetti](/confetti.html.md) |
| `components/countdown` | [Countdown](/countdown.html.md) |
| `components/data-table` | [Data table](/data-table.html.md) |
| `components/datepicker` | [Date picker](/datepicker.html.md) |
| `components/description-list` | [Description list](/description-list.html.md) |
| `components/dialog` | [Dialogs](/dialogs.html.md) |
| `components/docked-display` | [Date picker](/datepicker.html.md) |
| `components/drag-handle` | [Drag handle](/drag-handle.html.md) |
| `components/empty-state` | [Empty state](/empty-state.html.md) |
| `components/expanding-card` | [Cards](/cards.html.md) |
| `components/fab-menu` | [FAB](/floating-action-button.html.md) |
| `components/forms/checkboxes` | [Checkboxes](/checkboxes.html.md) |
| `components/forms/color-picker` | [Color picker](/color-picker.html.md) |
| `components/forms/color-swatches` | [Color swatches](/color-swatches.html.md) |
| `components/forms/drop-zone` | [Drop zone](/drop-zone.html.md) |
| `components/forms/fieldset` | [Fieldsets](/fieldsets.html.md) |
| `components/forms/file-input` | [Text fields](/text-inputs.html.md) |
| `components/forms/input-fields` | [Text fields](/text-inputs.html.md) |
| `components/forms/radio-buttons` | [Radio](/radio-buttons.html.md) |
| `components/forms/rating` | [Rating](/rating.html.md) |
| `components/forms/select` | [Select](/select.html.md) |
| `components/forms/slider` | [Slider](/slider.html.md) |
| `components/forms/switches` | [Switches](/switches.html.md) |
| `components/funnel-chart` | [Funnel chart](/funnel-chart.html.md) |
| `components/heatmap-chart` | [Heatmap chart](/heatmap-chart.html.md) |
| `components/icon-buttons` | [Icon buttons](/icon-buttons.html.md) |
| `components/icons-material-design` | [Icons](/icons.html.md) |
| `components/image-compare` | [Image compare](/image-compare.html.md) |
| `components/keypad` | [Keypad](/keypad.html.md) |
| `components/kpi` | [KPI](/kpi.html.md) |
| `components/lightbox` | [Lightbox](/media.html.md) |
| `components/line-chart` | [Line chart](/line-chart.html.md) |
| `components/list` | [Lists](/lists.html.md) |
| `components/loading-indicator` | [Loading indicator](/loading-indicator.html.md) |
| `components/loading-overlay` | [Loading overlay](/loading-overlay.html.md) |
| `components/map` | [Map](/map.html.md) |
| `components/marquee` | [Marquee](/marquee.html.md) |
| `components/mega-menu` | [Mega menu](/mega-menu.html.md) |
| `components/menu` | [Menu](/menu.html.md) |
| `components/menubar` | [Menubar](/menubar.html.md) |
| `components/message` | [Message](/message.html.md) |
| `components/message-scroller` | [Message scroller](/message-scroller.html.md) |
| `components/mixed-chart` | [Mixed chart](/mixed-chart.html.md) |
| `components/modal-display` | [Time picker](/timepicker.html.md) |
| `components/navbar` | [App bar](/navbar.html.md) |
| `components/navigation-bar` | [Navigation bar](/navigation-bar.html.md) |
| `components/navigation-rail` | [Navigation rail](/navigation-rail.html.md) |
| `components/org-chart` | [Organization chart](/org-chart.html.md) |
| `components/page-footer` | [Footer](/footer.html.md) |
| `components/pagination` | [Pagination](/pagination.html.md) |
| `components/panes` | [Panes](/panes.html.md) |
| `components/particles` | [Particles](/particles.html.md) |
| `components/pie-chart` | [Pie chart](/pie-chart.html.md) |
| `components/popover` | [Popover](/popover.html.md) |
| `components/progress` | [Preloader](/preloader.html.md) |
| `components/pull-to-refresh` | [Pull-to-refresh](/pull-to-refresh.html.md) |
| `components/questionnaire` | [Questionnaire](/questionnaire.html.md) |
| `components/radar-chart` | [Radar chart](/radar-chart.html.md) |
| `components/radial-chart` | [Radial chart](/radial-chart.html.md) |
| `components/rich-text-editor` | [Rich text editor](/rich-text-editor.html.md) |
| `components/sankey-chart` | [Sankey chart](/sankey-chart.html.md) |
| `components/scatter-chart` | [Scatter chart](/scatter-chart.html.md) |
| `components/scrim` | [Dialogs](/dialogs.html.md) |
| `components/scrollspy` | [Scrollspy](/scrollspy.html.md) |
| `components/search` | [Search](/search.html.md) |
| `components/show-more` | [Show more](/show-more.html.md) |
| `components/side-sheet` | [Side sheet](/side-sheet.html.md) |
| `components/skeleton` | [Skeleton](/skeleton.html.md) |
| `components/snackbar` | [Snackbar](/snackbar.html.md) |
| `components/split-button` | [Split button](/split-button.html.md) |
| `components/stat` | [Stat](/stat.html.md) |
| `components/stepper` | [Stepper](/stepper.html.md) |
| `components/swipe-actions` | [Swipe actions](/swipe-actions.html.md) |
| `components/table_of_contents` | [Scrollspy](/scrollspy.html.md) |
| `components/tabs` | [Tabs](/tabs.html.md) |
| `components/timeline` | [Timeline](/timeline.html.md) |
| `components/timepicker` | [Time picker](/timepicker.html.md) |
| `components/toolbar` | [Toolbars](/toolbars.html.md) |
| `components/tooltip` | [Tooltips](/tooltips.html.md) |
| `components/tour` | [Tour](/tour.html.md) |
| `components/transfer-list` | [Transfer list](/transfer-list.html.md) |
| `components/transitions` | [Transitions](/css-transitions.html.md) |
| `components/tree` | [Tree](/tree.html.md) |
| `components/treemap-chart` | [Treemap chart](/treemap-chart.html.md) |
| `tokens/contrast` | [Themes](/themes.html.md) |
| `tokens/elevation` | [Elevation](/shadow.html.md) |
| `tokens/motion` | [Transitions](/css-transitions.html.md) |
| `tokens/reference` | [Design tokens](/tokens.html.md) |
| `tokens/shape` | [Shapes](/shapes.html.md) |
| `tokens/stacking` | [Design tokens](/tokens.html.md) |
| `tokens/state` | [State layers](/state-layers.html.md) |
| `tokens/theme` | [Themes](/themes.html.md) |
| `tokens/vibrant` | [Themes](/themes.html.md) |
| `utilities/colors` | [Color](/color.html.md) |
| `utilities/defer-render` | [Lists](/lists.html.md) |
| `utilities/helpers` | [Helpers](/helpers.html.md) |
| `utilities/scroll-area` | [Scroll area](/scroll-area.html.md) |
| `utilities/shapes` | [Shapes](/shapes.html.md) |
| `utilities/spacing` | [Helpers](/helpers.html.md) |
| `utilities/typescale` | [Typography](/typography.html.md) |
| `utilities/visibility` | [Helpers](/helpers.html.md) |
| `utilities/z-depth` | [Elevation](/shadow.html.md) |
