-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgrid.css
More file actions
355 lines (309 loc) · 13 KB
/
Copy pathgrid.css
File metadata and controls
355 lines (309 loc) · 13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
/* ==========================================================================
swiss-style-theme / the grid layer
--------------------------------------------------------------------------
The typographic and grid discipline, which is the part of this register a
token file cannot hold.
tokens.css can hold a size and it can hold a leading. What it cannot hold
is the fact that they are one decision. On a baseline grid, choosing
--sw-text-h2 without also choosing --sw-leading-h2 puts the whole column
off the rhythm from that heading down, and nothing in a list of custom
properties says so. This file is where a size, its leading, its tracking
and its weight ship as a single class, so the pairing cannot come apart.
The same is true of the column grid. The container width, the column count
and the gutter are three tokens that only mean something together, and the
arithmetic that turns them into a layout lives here.
A NOTE ON SEPARABILITY
The neobrutalism sibling ships an extra layer, play.css, that can be
deleted whole. This file is not that. Delete it and the tokens still
resolve, the components still render, and what you have left is a page set
in one grotesque with no system running underneath it. That is a page, but
it is not this register.
What is separable is the last section: the two reveal classes. They are a
development aid, they paint nothing that ships, and removing them costs the
theme nothing but the ability to show its own skeleton.
Every value here is a var() reference to tokens.css. There is not one
colour literal in this file.
Requires tokens.css. Load it first:
<link rel="stylesheet" href="tokens/tokens.css" />
<link rel="stylesheet" href="components/grid.css" />
========================================================================== */
/* --------------------------------------------------------------------------
THE PAGE
The container is the reason the columns come out whole. At 1200px of
content a twelve-column grid with 24px gutters gives 78px columns, and a
rule drawn at a column boundary lands on the same pixel as the text edge
above it. Below the container width the columns go fractional and the grid
stops being something the reader can feel, which is the trade every fluid
grid makes and is worth naming rather than hiding.
--sw-container is the CONTENT width, so the max-width here has to add the
page padding back on. Setting max-width to the container alone would take
the padding out of the twelve columns instead of out of the margins, and
the tracks would come out at 74px rather than 78px. The arithmetic in
tokens.css would still be arithmetic, and it would no longer describe
anything on the screen.
-------------------------------------------------------------------------- */
.sw-page {
max-width: calc(var(--sw-container) + var(--sw-space-2) * 2);
margin-inline: auto;
padding-inline: var(--sw-space-2);
}
@media (min-width: 768px) {
.sw-page {
max-width: calc(var(--sw-container) + var(--sw-space-3) * 2);
padding-inline: var(--sw-space-3);
}
}
/* --------------------------------------------------------------------------
TYPE ROLES
Seven classes for seven steps. Each one binds a size to the leading it was
measured against, so the baseline rhythm holds without anyone having to
remember the pairing.
Weight is the only thing that varies inside a role, and it varies twice:
headings are bold, running text is regular. Anything that wants to be
louder than its role moves up a step rather than gaining a weight.
-------------------------------------------------------------------------- */
.sw-display {
font-family: var(--sw-font);
font-size: var(--sw-text-display);
line-height: var(--sw-leading-display);
letter-spacing: var(--sw-tracking-display);
font-weight: var(--sw-weight-bold);
margin: 0;
}
.sw-h1 {
font-family: var(--sw-font);
font-size: var(--sw-text-h1);
line-height: var(--sw-leading-h1);
letter-spacing: var(--sw-tracking-display);
font-weight: var(--sw-weight-bold);
margin: 0;
}
.sw-h2 {
font-family: var(--sw-font);
font-size: var(--sw-text-h2);
line-height: var(--sw-leading-h2);
letter-spacing: var(--sw-tracking-display);
font-weight: var(--sw-weight-bold);
margin: 0;
}
.sw-h3 {
font-family: var(--sw-font);
font-size: var(--sw-text-h3);
line-height: var(--sw-leading-h3);
letter-spacing: var(--sw-tracking-normal);
font-weight: var(--sw-weight-bold);
margin: 0;
}
/* The lead is the one running-text role set above body size. It is regular
weight on purpose: a bold lead would be a heading that had not admitted it. */
.sw-lead {
font-family: var(--sw-font);
font-size: var(--sw-text-lead);
line-height: var(--sw-leading-lead);
letter-spacing: var(--sw-tracking-normal);
font-weight: var(--sw-weight-regular);
margin: 0;
}
.sw-body {
font-family: var(--sw-font);
font-size: var(--sw-text-body);
line-height: var(--sw-leading-body);
letter-spacing: var(--sw-tracking-normal);
font-weight: var(--sw-weight-regular);
margin: 0;
}
.sw-meta {
font-family: var(--sw-font);
font-size: var(--sw-text-meta);
line-height: var(--sw-leading-meta);
letter-spacing: var(--sw-tracking-normal);
font-weight: var(--sw-weight-regular);
margin: 0;
}
/* Column heads and field labels. Caps at this size crowd, so this is the one
role that opens its tracking. */
.sw-meta-caps {
font-family: var(--sw-font);
font-size: var(--sw-text-meta);
line-height: var(--sw-leading-meta);
letter-spacing: var(--sw-tracking-label);
font-weight: var(--sw-weight-bold);
text-transform: uppercase;
margin: 0;
}
/* Secondary text keeps its size and changes its colour. A smaller step would
read as a different level, and it is not one. */
.sw-muted {
color: var(--sw-ink-muted);
}
/* Dates, call numbers, counts. The grotesque was drawn for exactly this job,
which is why the theme has no monospace family to fall back on. */
.sw-tabular {
font-variant-numeric: tabular-nums;
}
/* --------------------------------------------------------------------------
MEASURE
Prose that runs the full width of a twelve-column grid is unreadable at any
type size. Cap it.
-------------------------------------------------------------------------- */
.sw-measure {
max-width: var(--sw-measure);
}
/* --------------------------------------------------------------------------
BASELINE FLOW
Vertical space between siblings, in whole baselines. This is the second
half of the rhythm: the leading puts each line on the grid, and this keeps
the gaps between blocks on it too.
-------------------------------------------------------------------------- */
.sw-flow > * + * {
margin-top: var(--sw-space-3); /* 3 baselines */
}
.sw-flow-tight > * + * {
margin-top: var(--sw-space-2); /* 2 baselines */
}
.sw-flow-loose > * + * {
margin-top: var(--sw-space-6); /* 6 baselines */
}
/* --------------------------------------------------------------------------
RULES
The register's only structural device, in its three weights. A rule above a
block rather than below it, because in a column of stacked material the
rule belongs to the thing it introduces.
A RULE PAYS FOR ITS OWN WEIGHT
Each of these takes its border width back out of the padding beneath it, so
the distance from the top of the rule to the first line of type is a whole
number of baselines rather than a whole number plus a border.
This is easy to get wrong and invisible until you look for it. A 2px rule
over 16px of padding puts everything below it 18px down, which is two
pixels off the grid, and every block after it inherits the error. Turning
on .sw-reveal-baseline is the fastest way to find one.
-------------------------------------------------------------------------- */
.sw-rule-above {
border-top: var(--sw-rule-hair) solid var(--sw-rule);
padding-top: calc(var(--sw-space-2) - var(--sw-rule-hair));
}
.sw-rule-above-mid {
border-top: var(--sw-rule-mid) solid var(--sw-ink);
padding-top: calc(var(--sw-space-2) - var(--sw-rule-mid));
}
.sw-rule-above-heavy {
border-top: var(--sw-rule-heavy) solid var(--sw-ink);
padding-top: calc(var(--sw-space-3) - var(--sw-rule-heavy));
}
/* --------------------------------------------------------------------------
THE COLUMN GRID
One column below 768px and twelve above it.
There is no intermediate step. A six-column grid on a 600px screen gives
columns narrower than a word, so the spans would all collapse to full width
anyway and the grid would be a fiction maintained in the stylesheet. The
register is honest about structure, and the honest structure of a phone
column is one column.
-------------------------------------------------------------------------- */
.sw-grid {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: var(--sw-gutter);
}
@media (min-width: 768px) {
.sw-grid {
grid-template-columns: repeat(var(--sw-columns), minmax(0, 1fr));
}
/* Span classes set the end edge only, so a start class can be combined with
any of them without the two fighting over grid-column. */
.sw-col-1 { grid-column-end: span 1; }
.sw-col-2 { grid-column-end: span 2; }
.sw-col-3 { grid-column-end: span 3; }
.sw-col-4 { grid-column-end: span 4; }
.sw-col-5 { grid-column-end: span 5; }
.sw-col-6 { grid-column-end: span 6; }
.sw-col-7 { grid-column-end: span 7; }
.sw-col-8 { grid-column-end: span 8; }
.sw-col-9 { grid-column-end: span 9; }
.sw-col-10 { grid-column-end: span 10; }
.sw-col-11 { grid-column-end: span 11; }
.sw-col-12 { grid-column-end: span 12; }
/* Asymmetry is the register's normal state, and it is built by starting a
block somewhere other than column one. */
.sw-start-1 { grid-column-start: 1; }
.sw-start-2 { grid-column-start: 2; }
.sw-start-3 { grid-column-start: 3; }
.sw-start-4 { grid-column-start: 4; }
.sw-start-5 { grid-column-start: 5; }
.sw-start-6 { grid-column-start: 6; }
.sw-start-7 { grid-column-start: 7; }
.sw-start-8 { grid-column-start: 8; }
.sw-start-9 { grid-column-start: 9; }
.sw-start-10 { grid-column-start: 10; }
.sw-start-11 { grid-column-start: 11; }
.sw-start-12 { grid-column-start: 12; }
}
/* ==========================================================================
THE REVEAL
--------------------------------------------------------------------------
Everything below this line is a development aid. It paints two overlays
that draw the structure the rest of the file is built on: the columns, and
the baseline. Delete this section and nothing else in the theme changes.
It is here because in this register the skeleton is the argument. A page
that claims a grid discipline should be able to show the grid, and a reader
evaluating whether the discipline is real should not have to take it on
trust. Turning the overlay on is the fastest way to find the block that was
nudged four pixels to make something fit.
MECHANICS
Both overlays are pseudo-elements at z-index -1 on a host that carries
isolation: isolate. The isolation is what makes the layering deterministic:
it turns the host into a stacking context, so the overlay paints above the
host's own background and below every descendant. Without it a negative
z-index child can slide behind the host's background and disappear, and
z-index 0 would put the overlay on top of the text instead.
The columns overlay uses ::before and the baseline overlay uses ::after, so
a host carrying both classes gets both.
========================================================================== */
/* The column band width, derived the same way the grid derives it:
twelve columns share what is left after eleven gutters. */
.sw-reveal-columns {
--sw-reveal-band: calc(
(100% - (var(--sw-columns) - 1) * var(--sw-gutter)) / var(--sw-columns)
);
position: relative;
isolation: isolate;
}
/* Below 768px the grid is one column, so there is nothing to reveal and the
overlay paints nothing rather than drawing twelve bands that are not
there. */
@media (min-width: 768px) {
.sw-reveal-columns::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
pointer-events: none;
background-image: repeating-linear-gradient(
to right,
var(--sw-reveal-column) 0,
var(--sw-reveal-column) var(--sw-reveal-band),
transparent var(--sw-reveal-band),
transparent calc(var(--sw-reveal-band) + var(--sw-gutter))
);
}
}
/* One line per baseline. The lines are measured from the top of this
element's padding box, so put the class on a block whose top edge is
already on the grid or every line will read as off by the same amount. */
.sw-reveal-baseline {
position: relative;
isolation: isolate;
}
.sw-reveal-baseline::after {
content: "";
position: absolute;
inset: 0;
z-index: -1;
pointer-events: none;
background-image: repeating-linear-gradient(
to bottom,
var(--sw-reveal-baseline) 0,
var(--sw-reveal-baseline) 1px,
transparent 1px,
transparent var(--sw-baseline)
);
}