Responsive
Shared viewport thresholds for layouts that depend on the screen width.
01Preview
--narrow width < 48rem Active--medium width < 70rem Activenot (--medium) width ≥ 70rem ActiveViewport: measured in the browser. Resize the window to cross a threshold.
02Responsive breakpoints
Two viewport thresholds are build-time custom media definitions from breakpoints.css. Each excludes its boundary and applies to every narrower viewport, so a narrow viewport matches both. Use not for the range above a threshold.
| Token | Role | Definition |
|---|---|---|
--narrow | Phone-sized layouts: page margins, stacked shells and menus. | (width < 48rem) |
--medium | Tablets and narrow desktops: collapsed navigation and editorial columns. | (width < 70rem) |
@media (--narrow) {
.collection {
--layout-gap-inline: var(--space-4);
}
}
@media not (--medium) {
.article {
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
}
Thresholds are in rem, so they follow the browser's text size: enlarged text reaches the narrower layouts sooner. A rem in a media query refers to the browser's initial font size, not to the root element's.
Use these aliases in the owning component's styles. The package's Vite factory supplies and expands them through PostCSS; other consumers must configure @csstools/postcss-global-data and postcss-custom-media with @dg/ui/breakpoints.css.
Custom media are not runtime CSS variables: var() cannot provide a media-query threshold. Keep breakpoints out of runtime foundation imports. Preference queries and input capabilities remain native conditions.
03Viewport or container
Page structure follows the viewport: margins, header, footer, navigation and editorial columns. A reusable block that can sit in a full page, a sidebar or a panel follows its own width instead.
| Component | Condition |
|---|---|
Page, Header, Footer, Tabs | --narrow: smaller margins and gaps; header and footer wrap or stack. |
ChatWindow | --narrow: the launcher moves closer to the corner and hides its badge; the floating dialog fits the screen. |
Header navigation | --medium: links move into the menu. |
Page with an aside | --medium: the aside stacks between the header and the content. |
Text fields, ChatComposer | (pointer: coarse): at least 1rem, so touch browsers do not zoom on focus. |
Grid | Container query: one column at 40rem of its own width or less. |
Cards | Measured track width: as many whole cards as minWidth allows. |
Align app layouts with these conditions when they must change together, such as an editorial column that collapses with the header navigation at --medium.
04Units
Size layout in rem, so it follows the reader's text size together with the breakpoints: page, panel and column widths, heights, maximum widths, flex bases and type sizes. Spacing already does, through the --space-* scale. Set letter spacing in em, relative to the text it tracks.
Keep px for geometry that must not grow with text: strokes such as --border-width, the focus stroke and offsets, drawings and icons, optical adjustments and control targets such as --control-min-size. Browser zoom still enlarges them; only the text-size preference leaves them unchanged.