Layout without breakpoints

A fluid scale for type and space, eight primitives that lay out by their own width (so they behave the same in a sidebar, a card or a whole page), and an opt-in base that finishes plain HTML.

  • kit-layout.css
  • 3.2 KB brotli
  • after kit.css
  • No script needed

Use it

<link rel="stylesheet" href="https://openvibe.network/shared/kit.css">
<link rel="stylesheet" href="https://openvibe.network/shared/kit-layout.css">

The fluid scale

Every step grows with the screen from 320 to 1240 px by clamp(): 16 px text on a phone, 18 px on a wide screen, and the headings more. Resize the window and watch it move.

Aa--step--211.1–11.5 px
Aa--step--113.3–14.4 px
Aa--step-016–18 px
Aa--step-119.2–22.5 px
Aa--step-223–28.1 px
Aa--step-327.6–35.2 px
Aa--step-433.2–43.9 px
Aa--step-539.8–54.9 px
--space-3xs4–4.5 px
--space-2xs8–9 px
--space-xs12–13.5 px
--space-s16–18 px
--space-m24–27 px
--space-l32–36 px
--space-xl48–54 px
--space-2xl64–72 px
--space-3xl96–108 px

Eight primitives

Each box below is the real thing. On a computer, drag its corner to make it narrower: the switcher stacks, the sidebar goes under, the grid drops a column.

Stack .ov-stack

One under another, --gap apart. The rhythm of a column.

Title
One line about it
The action
The HTML · 5 lines
<div class="ov-stack" style="--gap: var(--space-xs)">
  <div>Title</div>
  <div>One line about it</div>
  <div>The action</div>
</div>

Cluster .ov-cluster

A wrapping row: tags, buttons, a toolbar. It never overflows; it wraps.

IRL Seattle Night Music Chat picks Walking
The HTML · 8 lines
<div class="ov-cluster">
  <span>IRL</span>
  <span>Seattle</span>
  <span>Night</span>
  <span>Music</span>
  <span>Chat picks</span>
  <span>Walking</span>
</div>

Sidebar .ov-sidebar

A side part --side wide beside the rest; it goes under once the rest would be narrower than --min.

The rest of the page
The HTML · 4 lines
<div class="ov-sidebar" style="--side: 12rem; --min: 60%">
  <aside>The side, 12rem</aside>
  <div>The rest of the page</div>
</div>

Switcher .ov-switcher

All side by side, or all stacked once the box is narrower than --min: never two and one.

Free
Creator
Studio
The HTML · 5 lines
<div class="ov-switcher" style="--min: 36rem">
  <div>Free</div>
  <div>Creator</div>
  <div>Studio</div>
</div>

Grid .ov-grid

As many columns of at least --min as fit, and one on a phone.

Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
The HTML · 8 lines
<div class="ov-grid" style="--min: 9rem">
  <div>Card 1</div>
  <div>Card 2</div>
  <div>Card 3</div>
  <div>Card 4</div>
  <div>Card 5</div>
  <div>Card 6</div>
</div>

Rail .ov-rail

One row that scrolls sideways and snaps: a long list that never makes a long page.

Clip 1
Clip 2
Clip 3
Clip 4
Clip 5
Clip 6
Clip 7
The HTML · 9 lines
<div class="ov-rail" style="--item: 10rem">
  <div>Clip 1</div>
  <div>Clip 2</div>
  <div>Clip 3</div>
  <div>Clip 4</div>
  <div>Clip 5</div>
  <div>Clip 6</div>
  <div>Clip 7</div>
</div>

Cover .ov-cover

A box at least --min tall, its .is-centre child in the middle: a hero, an empty page.

Above

In the middle

Below

The HTML · 5 lines
<section class="ov-cover" style="--min: 15rem">
  <p>Above</p>
  <h2 class="is-centre">In the middle</h2>
  <p>Below</p>
</section>

Frame .ov-frame

A box of --ratio that crops a picture or a video to fill it.

The HTML · 3 lines
<div class="ov-frame" style="--ratio: 21 / 9">
  <img src="/brand/openvibe-mark-wide.svg" alt="">
</div>

The classless base

Put .ov-base on <body> or <main>, and plain HTML looks finished. Every rule is inside :where(), so your own rules always win.

A plain heading

Plain text keeps to a readable measure, with a link, some code and a mark.

  • A list, spaced to breathe
  • On the site's own theme
A quote stands apart.
PlanPrice
Creator$6
The HTML · 9 lines
<main class="ov-base">
  <h2>A plain heading</h2>
  <p>Plain text keeps to a readable measure, with <a href="/kit/layout">a link</a>, some <code>code</code> and <mark>a mark</mark>.</p>
  <ul><li>A list, spaced to breathe</li><li>On the site's own theme</li></ul>
  <blockquote>A quote stands apart.</blockquote>
  <table><tr><th>Plan</th><th>Price</th></tr><tr><td>Creator</td><td>$6</td></tr></table>
  <label for="kt-base-name">Your name</label><input id="kt-base-name" placeholder="Ana">
  <button type="button">Save</button>
</main>