CEM D1x Breakpoints & Responsive Ranges — Window Size Classes (CEM × M3 × MUI)

Status: Canonical (v1.0) Last updated: 2025-12-23 Taxonomy placement: D1x. Layout Framing (Space & Rhythm extension) Audience: Design Systems, Product Design, Front-End Engineering


CEM first rule: If an adapter’s breakpoint names or defaults conflict with CEM semantics, CEM semantics win. Adapters translate to their own keyspaces; the consumer-facing vocabulary remains compact/medium/expanded/large/xlarge.

CEM uses breakpoints as a layout framing primitive that selects canonical layout archetypes (single-pane, two-pane, multi-pane) based on available space. Breakpoints express semantic meaning about available UI space, not device categories.

Companion specs:

Table of contents

  1. Scope
  2. Design principles
  3. Token taxonomy
  4. Window size classes
  5. Token surface (CSS)
  6. Adapter mapping
  7. Usage guidance
  8. Container queries extension
  9. Governance and versioning
  10. Canonical token summary
  11. References

1. Scope

1.1 What D1x controls

D1x (Breakpoints) defines:

1.2 What D1x does not define

D1x does not define:


2. Design principles

2.0 CEM first rule: semantics before adapters

CEM breakpoint semantics are defined by available layout space and consumer intent (one-pane vs two-pane vs multi-pane), not by framework defaults (for example, md meaning “900px” in MUI). Treat framework breakpoints as an adapter layer.

2.1 Semantics express available space, not devices

A breakpoint expresses available UI space (window/container), not "tablet vs desktop". Do not implement isTablet-style logic based on breakpoint names.

2.2 Bounded variation

Breakpoints are a small, stable vocabulary. Prefer 3–5 ranges, not dozens of product-specific micro-breakpoints.

2.3 Breakpoints select layouts; details are separate

Breakpoints choose canonical layout archetypes (one-pane → two-pane → multi-pane). Spacing, coupling, and stroke rules stay governed by their own dimensions (D1/D2/D5).

2.4 Cross-dimension invariants


3. Token taxonomy

3.1 Two-layer model

CEM breakpoints use a two-layer model:

Basis bounds (numeric boundaries)
  --cem-bp-{axis}-{range}-{min|max}
        │
        ▼
Semantic ranges (consumer vocabulary)
  compact | medium | expanded | large | xlarge

3.2 Why two layers?


4. Window size classes

CEM adopts the Material Design 3 window size class vocabulary as the primary reference because it is intentionally device-agnostic and defined on available width/height.

4.1 Width ranges (semantic)

CEM rangeMeaning (consumer)Width — reference
compactsingle-pane default; tight navigation< 600dp
mediumtwo-pane possible; avoid over-wide lines600dp ≤ w < 840dp
expandedtwo-pane comfortable; navigation rail viable840dp ≤ w < 1200dp
largemulti-pane viable; guard against sparse "stretch"1200dp ≤ w < 1600dp
xlargedesktop-class; constrain reading width, increase density≥ 1600dp

4.2 Height ranges (semantic)

Height is usually secondary due to vertical scrolling, but matters for landscape phones and split-screen.

CEM rangeHeight — referenceDevice representation (informative)
compact< 480dp99.78% of phones in landscape
medium480dp ≤ h < 900dp96.56% of tablets in landscape, 97.59% of phones in portrait
expanded≥ 900dp94.25% of tablets in portrait

Note: Most apps adapt based on width alone. Consider height when width is medium while height is compact (e.g., phones in landscape), where two-pane layouts are often impractical.


5. Token surface (CSS)

5.1 Basis tokens (bounds)

These tokens are numeric bounds for ranges, consumed by build-time systems (PostCSS/@custom-media), JS breakpoints, and runtime CSS systems. Epsilon is used when expressing half-open intervals [min, nextMin) as exclusive max-width/max-height values.

cem-bp-basis
TokenValueDescriptiontier
--cem-bp-epsilon0.01pxDefault epsilon for exclusive upper boundsrequired
--cem-bp-epsilon-css0.01pxExplicit CSS adapter epsilon (same as default)recommended
--cem-bp-epsilon-mui0.05pxMUI adapter epsilon (theme.breakpoints.step = 5 parity)recommended
--cem-bp-width-compact-min0pxCompact width lower boundrequired
--cem-bp-width-compact-maxcalc(var(--cem-bp-width-medium-min) - var(--cem-bp-epsilon))Compact width upper bound (exclusive)required
--cem-bp-width-medium-min600pxMedium width lower bound (M3 reference)required
--cem-bp-width-medium-maxcalc(var(--cem-bp-width-expanded-min) - var(--cem-bp-epsilon))Medium width upper bound (exclusive)required
--cem-bp-width-expanded-min840pxExpanded width lower bound (M3 reference)required
--cem-bp-width-expanded-maxcalc(var(--cem-bp-width-large-min) - var(--cem-bp-epsilon))Expanded width upper bound (exclusive)recommended
--cem-bp-width-large-min1200pxLarge width lower bound (M3 reference)recommended
--cem-bp-width-large-maxcalc(var(--cem-bp-width-xlarge-min) - var(--cem-bp-epsilon))Large width upper bound (exclusive)recommended
--cem-bp-width-xlarge-min1600pxXlarge width lower bound (no max; unbounded)recommended
cem-bp-height
TokenValueDescriptiontier
--cem-bp-height-compact-min0pxCompact height lower boundrecommended
--cem-bp-height-compact-maxcalc(var(--cem-bp-height-medium-min) - var(--cem-bp-epsilon))Compact height upper bound (exclusive)recommended
--cem-bp-height-medium-min480pxMedium height lower boundrecommended
--cem-bp-height-medium-maxcalc(var(--cem-bp-height-expanded-min) - var(--cem-bp-epsilon))Medium height upper bound (exclusive)recommended
--cem-bp-height-expanded-min900pxExpanded height lower bound (no max; unbounded)recommended

5.2 Active width tracker

The @media helpers in Block B set this token so that JS can read the current breakpoint class via getComputedStyle(document.documentElement).getPropertyValue('--cem-bp-active-width').trim(). There is no :root default; the value is always resolved from @media context.

cem-bp-active
TokenDescriptiontier
--cem-bp-active-widthCurrent active width class (compact/medium/expanded/large/xlarge); read via JSrecommended
--cem-bp-active-heightCurrent active height class (short/medium/tall); read via JSrecommended

5.3 Generator helper: @media range data

These tables drive the @media and height helper blocks in the generator. They are not token sources — rows do not begin with --cem-* and are excluded from the manifest automatically.

cem-bp-media-ranges
rangemin-widthmax-widthdescription
compact0px599.99pxmax-only rule; M3 compact width
medium600px839.99pxM3 medium width
expanded840px1199.99pxM3 expanded width
large1200px1599.99pxM3 large width
xlarge1600px—min-only rule; M3 xlarge width
cem-bp-height-ranges
rangemin-heightmax-heightdescription
compact0px479.99pxmax-only rule; compact height
medium480px899.99pxmedium height
expanded900px—min-only rule; expanded height

5.4 Normative rules

5.5 @custom-media (where supported; NOT emitted in production output)

@custom-media --cem-compact  (max-width: calc(600px - 0.01px));
@custom-media --cem-medium   (min-width: 600px) and (max-width: calc(840px - 0.01px));
@custom-media --cem-expanded (min-width: 840px) and (max-width: calc(1200px - 0.01px));
@custom-media --cem-large    (min-width: 1200px) and (max-width: calc(1600px - 0.01px));
@custom-media --cem-xlarge   (min-width: 1600px);

/* Height classes */
@custom-media --cem-height-compact  (max-height: calc(480px - 0.01px));
@custom-media --cem-height-medium   (min-height: 480px) and (max-height: calc(900px - 0.01px));
@custom-media --cem-height-expanded (min-height: 900px);

/*
 * NOTE:
 * The `0.01px` epsilon is illustrative. Align epsilon to your toolchain:
 * - If you use MUI default step=5, prefer 0.05px for exclusive upper bounds.
 */


6. Adapter mapping

6.1 Material Design 3 (reference)

M3 window size classes provide the reference lattice for this spec. CEM directly adopts M3's width/height boundaries.

M3 classWidth boundary
Compact< 600dp
Medium600–839dp
Expanded840–1199dp
Large1200–1599dp
Extra-large≥ 1600dp

6.2 Material UI (MUI) default breakpoints

MUI keyDefault value
xs0px
sm600px
md900px
lg1200px
xl1536px

Gap analysis: MUI lacks the 840px boundary (M3 expanded) and uses 1536px instead of 1600px for xl.

CEM semantics are stable; your MUI integration chooses an adapter strategy.

Strategy A (recommended for most MUI codebases): keep MUI keys, align values to the CEM lattice.
This avoids custom keys and minimizes TypeScript/module-augmentation friction while matching CEM/M3 boundaries.

const theme = createTheme({
  breakpoints: {
    values: {
      xs: 0,
      sm: 600,   // medium lower bound
      md: 840,   // expanded lower bound (repurposes MUI `md`)
      lg: 1200,  // large lower bound
      xl: 1600,  // xlarge lower bound (repurposes MUI `xl`)
    },
  },
});

Strategy B (semantic purity): replace MUI keys with CEM keys (compact/medium/expanded/large/xlarge).
This yields the cleanest vocabulary, but requires TypeScript module augmentation and a broader migration.

Strategy C (bridge / mixed keyspace): add expanded/xlarge alongside the defaults.
Use only for incremental migration. This introduces two “large-ish” keys (xl vs xlarge)—treat the mixed period as transitional.

6.4 Mapping tables

Strategy A mapping (aligned values, default keys):

CEM rangeMUI binding
compactdown('sm')
mediumbetween('sm', 'md')
expandedbetween('md', 'lg')
largebetween('lg', 'xl')
xlargeup('xl')

Strategy B mapping (CEM keys as MUI keys):

CEM rangeMUI binding
compactdown('medium') (or only('compact') if you define it explicitly)
mediumbetween('medium', 'expanded')
expandedbetween('expanded', 'large')
largebetween('large', 'xlarge')
xlargeup('xlarge')

Strategy C mapping (mixed keyspace, transitional):

CEM rangeMUI binding
compactdown('sm')
mediumbetween('sm', 'expanded')
expandedbetween('expanded', 'lg')
largebetween('lg', 'xlarge')
xlargeup('xlarge')

7. Usage guidance

7.1 What SHOULD change at a breakpoint

Breakpoints trigger layout archetype changes:

7.2 What SHOULD NOT change at a breakpoint

7.3 Responsive design principles

  1. Mobile-first: start with compact layout, progressively enhance.
  2. Content-driven: let content needs determine when to introduce panes.
  3. Density-aware: larger screens can support higher information density (D2).
  4. Line-length conscious: constrain reading width in xlarge to preserve D6 readability (45–75 characters optimal).

7.4 Orthogonal responsiveness strategy

Breakpoints (D1x) classify available space. Responsiveness strategy (D1y) classifies how layout adapts. Treat these as orthogonal axes:

In CEM, the default posture is intrinsic-first; introduce breakpoint-driven behavior primarily when the meaning of layout changes (e.g., one-pane → two-pane), not to compensate for rigid mechanics. See cem-responsive.md.

7.5 Component mapping checklist

Use this table to choose where D1x breakpoints apply and which D1y strategy to prefer. The “Responsiveness strategy” column is normative for component recipes; other columns are guidance.

Component familyBreakpoint role (D1x)Preferred query contextResponsiveness strategy (D1y)Notes
App shell navigation (bottom bar / rail / drawer)Yes (archetype switch)Viewport/windowbreakpoint / hybridBreakpoints change navigation meaning; keep D2 invariants.
Master–detail / list–detail panesYes (introduce second pane)Viewport/window, sometimes containerhybridUse intrinsic sizing within panes; breakpoint decides when the second pane exists.
Card listings / galleriesUsually NoContainer firstintrinsic / containerPrefer wrap or auto-fit/minmax(); avoid fixed column counts.
Forms (field groups)RareContainer firstintrinsicPrefer flowing groups and min()/max() widths; breakpoint only for major reflow.
Data tables / dense comparison gridsSometimesContainer firstcontainer / hybridContainer size often determines column visibility / stacking.
Side panels, filters, inspector panesSometimesContainer firstcontainer / hybridThe panel width (not viewport) is the driver in split UI.
Overlays (dialogs, popovers, tooltips)No (typically)Container/anchorintrinsicSize to content and coupling; do not key to viewport breakpoints.

7.6 Intrinsic layouts disclaimer (flex/grid, wrapping, and container-first responsiveness)

CEM breakpoints define semantic ranges of available space. They do not mandate a fixed grid, fixed column count, or device-class assumptions.

A well-designed intrinsic layout can span small mobile → large desktop → ultra-wide without introducing additional breakpoint classes. Use breakpoints primarily when the meaning of layout changes (e.g., introducing a second pane), not to compensate for rigid layout mechanics.

7.7 Content-first, component-first responsiveness patterns (informative)

7.8 Should CEM introduce a token value like responsive?

Generally no: “responsive” is an implementation property (intrinsic vs breakpoint-driven), not a breakpoint range.

If you need to mark that a layout is intended to be intrinsic-responsive (wrapping/container-first), prefer a documentation tag in component mapping (e.g., strategy: intrinsic) or an adapter/build-time flag. Avoid encoding “responsive” as an extra breakpoint value because it conflates method with available space semantics.


8. Container queries extension

Some UIs (split panes, sidebars, embedded widgets) need size classes based on container width, not viewport.

8.1 Container bounds (optional)

These reference values reuse the same semantic lattice as the viewport breakpoints. Consumers place them in their own @container rules; CEM does not emit @container selectors directly. Uses --cem-bp-epsilon directly — no separate --cem-cq-epsilon needed.

R-D1x-WRAP resolved: CEM v1 documents the containment requirement but does not ship a wrapper component. Component libraries and products must opt each queryable host into containment with container-type (and optionally container-name). This keeps the token package framework-neutral and avoids adding layout side effects to consumers' DOM. A wrapper may still be built by an adapter library, but it is not part of the canonical D1x token output.

cem-bp-cq
TokenValueDescriptiontier
--cem-cq-width-compact-maxcalc(var(--cem-cq-width-medium-min) - var(--cem-bp-epsilon))Compact container upper bound (exclusive)recommended
--cem-cq-width-medium-min600pxMedium container lower boundrecommended
--cem-cq-width-medium-maxcalc(var(--cem-cq-width-expanded-min) - var(--cem-bp-epsilon))Medium container upper bound (exclusive)recommended
--cem-cq-width-expanded-min840pxExpanded container lower boundrecommended
--cem-cq-width-expanded-maxcalc(var(--cem-cq-width-large-min) - var(--cem-bp-epsilon))Expanded container upper bound (exclusive)recommended
--cem-cq-width-large-min1200pxLarge container lower boundrecommended

8.2 Container query usage

.container {
  container-type: inline-size;
  container-name: card;
}

@container card (max-width: 599.98px) {
  /* compact container layout */
}

@container card (min-width: 600px) and (max-width: 839.98px) {
  /* medium container layout */
}

Implementation requirements:

Material UI (optional): container query adapter and shorthand

Material UI exposes theme.containerQueries and an sx shorthand using @<size> / @<size>/<name>.

// Theme API (breakpoint keys or unitless widths)
theme.containerQueries.up('sm');        // => '@container (min-width: 600px)'
theme.containerQueries('card').up(600); // => '@container card (min-width: 600px)'
// sx shorthand (unitless sizes render as px; `@500px` is invalid syntax)
<Box
  sx={{
    '@': { p: 1 },       // 0px
    '@600': { p: 2 },    // 600px
    '@840': { p: 3 },    // 840px
  }}
/>

8.3 Normative requirements


9. Governance and versioning

9.1 Breaking (major)

Treat as breaking if you:

9.2 Non-breaking (minor/patch)

Treat as non-breaking if you:


10. Token manifest index

Token tier is encoded in the tier column of each source table. The manifest validator derives expected token names from these tables using the same XPath pattern as cem-breakpoints.html.

Source table h6 idTokens coveredValidator derivation
cem-bp-basis--cem-bp-epsilon* (3) + --cem-bp-width-* (9) = 12 tokensone token per row
cem-bp-height--cem-bp-height-* (5 tokens)one token per row
cem-bp-active--cem-bp-active-width + --cem-bp-active-height (2 tokens; set by @media, no :root default)one token per row
cem-bp-cq--cem-cq-width-* (6 tokens)one token per row

Generator helper tables cem-bp-media-ranges and cem-bp-height-ranges are NOT token sources — their rows start with range names (not --cem-*), so they are automatically excluded from the manifest.

Note: @custom-media is NOT emitted in production output per Principle P5. The @media helper block (Block B) sets --cem-bp-active-width for JS consumption. The @container helper block (Block C) is intentionally not emitted after R-D1x-WRAP resolution; --cem-cq-* reference values are available in :root for consumers or adapter-owned wrappers to use in their own @container rules.


11. References

Internal

External


This spec is the canonical D1x contract for CEM responsive breakpoints and adapter mapping.