---
title: "Border"
subtitle: "Position, width, style and colour, composed"
description: "How borders are built for the web: a structural class sets the position, while width, style and colour classes each modify a single concern independently."
author: "Studio"
section: "Website"
subsection: "Foundations"
order: 6
status: "published"
---
A border is composed rather than chosen: one structural class sets where it sits, and width, style and colour classes each modify a single concern. That is why the system has no `.border-top-m` — it would fuse two decisions into one name, and then need duplicating for every other combination. The token values behind these classes are on the [Tokens](/website/tokens.html) page.
## Structure
A structural class sets the position. On its own it draws `var(--border-s)`, solid, in `var(--border-primary)`.
All sides
Medically reviewed
Bottom
Sources and references
Right
Next in this series
```html
All sides
Top only
```
| Class | Where it draws |
| --- | --- |
| `.border` | Every side — cards, panels, anything enclosed |
| `.border-top` | Above the element, so it reads as a separator from what precedes it |
| `.border-bottom` | Below, the usual rule between stacked article rows |
| `.border-left` | Beside, for an aside or editor's note set off from the column |
| `.border-right` | Beside, on the trailing edge |
## Width
Width is a separate class from position, so any thickness can sit on any side.
Small — the default
A hairline between article rows
Large
A heavy emphasis rule
```html
Medium on all sides
```
| Class | Token | Value and use |
| --- | --- | --- |
| `.border-s` | `var(--border-s)` | 1px (0.0625rem) — the default, and what almost everything on the site uses |
| `.border-m` | `var(--border-m)` | 1.5px (0.09375rem), for a rule that needs to register as deliberate |
| `.border-l` | `var(--border-l)` | 3px (0.1875rem). Nothing in the shipped system uses it; it is there for emphasis a page might need |
Widths are declared in rem, not pixels, so a border thickens with the reader's browser zoom and root font-size setting rather than staying pinned to a device pixel.
## Style
Style is the third axis, and it carries meaning: a border's pattern says how settled the thing inside it is.
Solid — the default
Published
Dashed
Draft — not yet reviewed
```html
Dashed
```
| Class | Reads as |
| --- | --- |
| `.border-solid` | Settled and structural — the default |
| `.border-dashed` | Provisional, which is why it suits drafts and empty states |
| `.border-dotted` | Lighter still, for a slot that is waiting on content |
## Colour
Border colours are semantic tokens, so they re-resolve in dark mode without the element knowing.
Primary — the default
Watch the panel
Secondary
This month's newsletter
Faded
Diabetes · Nutrition · Mental Health
```html
Subtle
```
| Class | Token | Use |
| --- | --- | --- |
| `.border-primary` | `var(--border-primary)` | Structural edges that define a shape. It resolves to the text colour, so it inverts with the theme |
| `.border-secondary` | `var(--border-secondary)` | Decorative rules, where the line is not load-bearing |
| `.border-faded` | `var(--border-faded)` | Hairlines — a division you should feel rather than see |
## Radius
Radius has no utility classes. Apply the token in CSS.
m — 10px
Live event — 14 May
xl — 24px
Community activations
```css
border-radius: var(--radius-m);
```
| Token | Value | Use |
| --- | --- | --- |
| `var(--radius-2xs)` | 2px | Barely softened — labels and small badges |
| `var(--radius-xs)` | 4px | Tags and small controls |
| `var(--radius-s)` | 6px | Inputs and buttons |
| `var(--radius-m)` | 10px | Cards |
| `var(--radius-l)` | 16px | Panels and dialogs |
| `var(--radius-xl)` | 24px | Large surfaces that need a soft edge |
| `var(--radius-pill)` | 999px | Chips and badges, where the shape is fully rounded |
## Composing
Each class modifies one concern, so they stack without fighting.
Top, medium, dashed, secondary
Draft — scheduled for review
Bottom, large, primary
Heart Health
All sides, faded, dotted
Newsletter sign-up
```html
Top, medium, dashed, secondary
```
## Rules
- **Never write a class that fuses two concerns.** `.border-top-m` looks convenient and then has to be duplicated for every other combination; the composable set already covers all of them.
- **Never hardcode a border value.** Width, colour and radius are all tokens, and a literal `1px solid #000` will not follow the theme into dark mode.
- **Reach for `.border-faded` first.** Most divisions on this site want to be felt rather than seen; primary ink is for edges that define a shape.