Responsive & breakpoints

Mobile-first breakpoint modifiers, custom and ranged breakpoints, and container queries.

1 min readv1

How breakpoint modifiers work#

A breakpoint modifier wraps a rule in a media query. Built-in breakpoints are min-width, so each one applies from its width upward (mobile-first):

HTML
<div nib="gtc=1fr; md:gtc=1fr 1fr; xl:gtc=repeat(4, 1fr)">

Modifier

Media query

xs:

(min-width: 480px)

sm:

(min-width: 576px)

md:

(min-width: 768px)

lg:

(min-width: 992px)

xl:

(min-width: 1024px)

2xl:

(min-width: 1200px)

3xl:

(min-width: 1440px)

4xl:

(min-width: 1536px)

Custom breakpoints#

Your breakpoints are merged over the built-ins — override a value or add new names:

TypeScript
export default defineConfig({
  breakpoints: {
    md: { min: 800 },                   // move md
    tablet: { min: 768, max: 1023 },    // a range
  },
});
HTML
<aside nib="tablet:d=none">   <!-- hidden only between 768 and 1023px -->
CSS
@media (min-width: 768px) and (max-width: 1023px) {
  .nib-972ikg { display: none }
}

Ordering#

Media rules are emitted after all base rules, in the order they first appear. Within one element, prefer ascending breakpoints (md: then lg:) so larger screens override smaller ones.

Recipes at a breakpoint#

A breakpoint in front of a recipe applies to every rule in it:

HTML
<div nib="md:card">   <!-- card styling from 768px up --></div>

Container queries#

Style an element by the size of its container instead of the viewport. Declare the container with ctnt (container-type) and put the @container rule in page or global CSS:

HTML
<div nib="ctnt=inline-size; ctnn=card">
  <div class="card-body">…</div>
</div>
CSS
@container card (min-width: 420px) {
  .card-body { display: grid; grid-template-columns: 120px 1fr; }
}

Next steps#