actual-css 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -3
- package/README.md +35 -30
- package/dist/actual.css +73 -4946
- package/dist/actual.full.css +7090 -0
- package/dist/actual.full.js +1 -0
- package/dist/actual.full.min.css +1 -0
- package/dist/actual.js +1 -1
- package/dist/actual.min.css +1 -1
- package/docs/design-notes/cascade-layer.md +34 -13
- package/docs/design-notes/column-layout.md +677 -0
- package/docs/design-notes/forced-colors.md +3 -0
- package/docs/design-notes/grid.md +612 -0
- package/docs/design-notes/naming.md +15 -0
- package/docs/design-notes/widget-primitives.md +1 -0
- package/docs/navigation.json +5 -1
- package/docs/pages/components/alert.md +16 -14
- package/docs/pages/components/aura.md +1 -1
- package/docs/pages/components/avatar.md +6 -6
- package/docs/pages/components/badge.md +7 -7
- package/docs/pages/components/button.md +16 -16
- package/docs/pages/components/card.md +13 -9
- package/docs/pages/components/chat.md +8 -8
- package/docs/pages/components/dialog.md +7 -7
- package/docs/pages/components/drawer.md +3 -3
- package/docs/pages/components/fab.md +7 -7
- package/docs/pages/components/navbar.md +9 -8
- package/docs/pages/components/pagination.md +4 -3
- package/docs/pages/components/skeleton.md +4 -4
- package/docs/pages/components/spinner.md +5 -5
- package/docs/pages/components/table.md +30 -5
- package/docs/pages/enhancements/flyout.md +13 -13
- package/docs/pages/enhancements/overview.md +1 -1
- package/docs/pages/enhancements/scrollspy.md +6 -6
- package/docs/pages/enhancements/status-bar.md +5 -1
- package/docs/pages/enhancements/tabs.md +6 -6
- package/docs/pages/enhancements/tooltip.md +1 -1
- package/docs/pages/examples/overview.md +39 -22
- package/docs/pages/forms/choice-cards.md +11 -6
- package/docs/pages/forms/controls.md +1 -1
- package/docs/pages/forms/detached-actions.md +1 -1
- package/docs/pages/forms/floating-field.md +10 -5
- package/docs/pages/forms/form-actions.md +1 -1
- package/docs/pages/forms/input-policy.md +1 -1
- package/docs/pages/forms/joined-controls.md +4 -4
- package/docs/pages/forms/labels.md +6 -6
- package/docs/pages/forms/otp.md +1 -1
- package/docs/pages/forms/overview.md +19 -19
- package/docs/pages/forms/password.md +1 -1
- package/docs/pages/forms/range.md +1 -1
- package/docs/pages/forms/states-and-sizes.md +41 -45
- package/docs/pages/forms/sticky-actions.md +3 -3
- package/docs/pages/forms/switch.md +110 -2
- package/docs/pages/forms/validation.md +9 -9
- package/docs/pages/foundations/philosophy.md +1 -1
- package/docs/pages/foundations/theming.md +17 -2
- package/docs/pages/foundations/tokens.md +22 -10
- package/docs/pages/foundations/typography.md +50 -20
- package/docs/pages/guides/bootstrap.md +11 -11
- package/docs/pages/guides/integrating-actual-css.md +186 -0
- package/docs/pages/guides/introduction.md +23 -26
- package/docs/pages/guides/modular-import.md +173 -0
- package/docs/pages/guides/progressive-enhancement.md +81 -78
- package/docs/pages/guides/tailwind.md +6 -8
- package/docs/pages/layout/app-shell.md +1 -1
- package/docs/pages/layout/center.md +1 -1
- package/docs/pages/layout/choosing.md +39 -0
- package/docs/pages/layout/column-layout.md +206 -0
- package/docs/pages/layout/frame.md +6 -1
- package/docs/pages/layout/grid.md +100 -102
- package/docs/pages/layout/list.md +1 -1
- package/docs/pages/layout/media.md +1 -1
- package/docs/pages/layout/overview.md +15 -2
- package/docs/pages/layout/scroll-snap.md +2 -2
- package/docs/pages/layout/scroll-target.md +45 -0
- package/docs/pages/layout/sidebar-layout.md +20 -19
- package/docs/pages/layout/stack.md +53 -1
- package/docs/pages/layout/switcher.md +10 -26
- package/docs/pages/layout/topbar.md +2 -2
- package/docs/pages/patterns/actions.md +1 -1
- package/docs/pages/patterns/code-block.md +1 -1
- package/docs/pages/patterns/exclusive-accordion.md +1 -1
- package/docs/pages/patterns/hierarchical-nav.md +1 -1
- package/docs/pages/patterns/icon-input.md +1 -1
- package/docs/pages/patterns/intent-nesting.md +1 -1
- package/docs/pages/patterns/navigation-list.md +1 -1
- package/docs/pages/patterns/overview.md +1 -1
- package/docs/pages/patterns/structured-lists.md +1 -1
- package/docs/pages/utilities/accessibility.md +3 -3
- package/docs/pages/utilities/flex.md +15 -15
- package/docs/pages/utilities/links.md +4 -4
- package/docs/pages/utilities/list.md +8 -8
- package/docs/pages/utilities/overflow.md +8 -8
- package/docs/pages/utilities/overview.md +1 -1
- package/docs/pages/utilities/shape.md +3 -3
- package/docs/pages/utilities/sizing-wrapping.md +23 -16
- package/docs/pages/utilities/spacing.md +20 -20
- package/docs/pages/utilities/text.md +10 -10
- package/llms.txt +46 -4
- package/package.json +42 -13
- package/scripts/reserved-classes.json +261 -0
- package/src/cli/actual-css.js +133 -0
- package/src/css/actual.css +1 -31
- package/src/css/actual.full.css +11 -2
- package/src/css/components/alert.css +17 -4
- package/src/css/components/badge.css +18 -6
- package/src/css/components/breadcrumb.css +1 -1
- package/src/css/components/button.css +19 -1
- package/src/css/components/card.css +27 -2
- package/src/css/components/drawer.css +27 -2
- package/src/css/components/flyout.css +5 -0
- package/src/css/components/index.css +32 -27
- package/src/css/components/join.css +8 -1
- package/src/css/components/key.css +2 -0
- package/src/css/components/menu.css +11 -1
- package/src/css/components/meter.css +4 -1
- package/src/css/components/modal.css +5 -0
- package/src/css/components/pagination.css +11 -0
- package/src/css/components/spinner.css +5 -0
- package/src/css/components/status-bar.css +5 -0
- package/src/css/components/surface.css +5 -0
- package/src/css/components/table.css +6 -0
- package/src/css/components/tooltip.css +5 -0
- package/src/css/core/index.css +9 -0
- package/src/css/core/print.css +18 -0
- package/src/css/{theme.css → core/theme.css} +20 -10
- package/src/css/{tokens.css → core/tokens.css} +15 -2
- package/src/css/{variants.css → core/variants.css} +3 -2
- package/src/css/effects/index.css +2 -0
- package/src/css/forms/base.css +8 -0
- package/src/css/forms/choice-card.css +5 -4
- package/src/css/forms/choice.css +49 -37
- package/src/css/forms/control.css +4 -1
- package/src/css/forms/custom-select.css +2 -0
- package/src/css/{optional → forms}/floating-field.css +25 -7
- package/src/css/forms/index.css +10 -13
- package/src/css/forms/native.css +15 -2
- package/src/css/{optional → forms}/otp.css +20 -16
- package/src/css/forms/switch.css +31 -29
- package/src/css/layout/app-shell.css +6 -0
- package/src/css/layout/center.css +13 -0
- package/src/css/layout/cluster.css +21 -0
- package/src/css/layout/column-layout.css +144 -0
- package/src/css/layout/container-query.css +13 -0
- package/src/css/layout/frame.css +19 -0
- package/src/css/layout/grid.css +141 -0
- package/src/css/layout/index.css +42 -0
- package/src/css/layout/measure.css +9 -0
- package/src/css/layout/media.css +10 -0
- package/src/css/layout/scroll-target.css +15 -0
- package/src/css/layout/scroller.css +41 -0
- package/src/css/layout/sidebar-layout.css +31 -0
- package/src/css/layout/stack.css +21 -0
- package/src/css/layout/switcher.css +23 -0
- package/src/css/{optional/layout-extra.css → layout/topbar.css} +0 -20
- package/src/css/typography/index.css +5 -0
- package/src/css/typography/lead.css +7 -0
- package/src/css/{components → typography}/overline.css +2 -2
- package/src/css/{prose.css → typography/prose.css} +53 -38
- package/src/css/{utilities.css → utilities/base.css} +2 -0
- package/src/css/utilities/index.css +3 -0
- package/src/js/escape.js +36 -0
- package/src/js/flyout.js +22 -12
- package/src/js/full.js +26 -0
- package/src/js/index.js +5 -21
- package/src/js/surface.js +1 -31
- package/src/js/tooltip.js +46 -18
- package/src/js/validation.js +1 -1
- package/src/tooling/css-bundle.js +308 -0
- package/dist/actual-themes.min.css +0 -1
- package/dist/optional.css +0 -1048
- package/dist/optional.min.css +0 -1
- package/docs/pages/guides/optional-components.md +0 -33
- package/src/css/grid.css +0 -109
- package/src/css/layout.css +0 -123
- package/src/css/optional/index.css +0 -10
- package/src/css/optional/scroller.css +0 -63
- package/src/css/print.css +0 -47
- package/src/css/themes/corporate.css +0 -60
- package/src/css/themes/cyberpunk.css +0 -60
- package/src/css/themes/dim.css +0 -33
- package/src/css/themes/edge.css +0 -117
- package/src/css/themes/forest.css +0 -65
- package/src/css/themes/gradient.css +0 -97
- package/src/css/themes/index.css +0 -47
- package/src/css/themes/indigo.css +0 -33
- package/src/css/themes/lavender.css +0 -66
- package/src/css/themes/mono.css +0 -60
- package/src/css/themes/neon.css +0 -66
- package/src/css/themes/ocean.css +0 -60
- package/src/css/themes/petrol.css +0 -64
- package/src/css/themes/spruce.css +0 -64
- package/src/css/themes/square.css +0 -65
- package/src/css/themes/sunset.css +0 -66
- /package/src/css/{optional → components}/chat.css +0 -0
- /package/src/css/{optional → components}/fab.css +0 -0
- /package/src/css/{base.css → core/base.css} +0 -0
- /package/src/css/{focus.css → core/focus.css} +0 -0
- /package/src/css/{intents.css → core/intents.css} +0 -0
- /package/src/css/{reset.css → core/reset.css} +0 -0
- /package/src/css/{optional → effects}/aura.css +0 -0
- /package/src/css/{optional → layout}/scroll-snap.css +0 -0
- /package/src/css/{optional/typography-fluid.css → typography/fluid.css} +0 -0
- /package/src/css/{optional/utilities-extra.css → utilities/extra.css} +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Column Layout
|
|
2
|
+
|
|
3
|
+
`.column-layout` is an explicit twelve-column composition canvas. Place regions
|
|
4
|
+
with `.column-span-N` and `.column-start-N`.
|
|
5
|
+
|
|
6
|
+
Reach for it when the placement of each region **is** the design. If the regions
|
|
7
|
+
are a collection, a known density, peers that switch together, or a main region
|
|
8
|
+
with an aside, one of the other primitives already says so — and says it with
|
|
9
|
+
intrinsic responsive behavior this one does not have.
|
|
10
|
+
|
|
11
|
+
```html demo
|
|
12
|
+
<div class="column-layout">
|
|
13
|
+
<main class="column-span-8 card">Main — 8 columns</main>
|
|
14
|
+
<aside class="column-span-4 card">Aside — 4 columns</aside>
|
|
15
|
+
</div>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Neither child names a start line, so grid auto-placement flows the aside into
|
|
19
|
+
columns 9 through 12.
|
|
20
|
+
|
|
21
|
+
## Spans
|
|
22
|
+
|
|
23
|
+
A span declares how many of the twelve units a region occupies.
|
|
24
|
+
|
|
25
|
+
```html demo
|
|
26
|
+
<div class="column-layout">
|
|
27
|
+
<div class="column-span-3 card">3</div>
|
|
28
|
+
<div class="column-span-6 card">6</div>
|
|
29
|
+
<div class="column-span-3 card">3</div>
|
|
30
|
+
</div>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
A child with no placement class spans the whole canvas, so a heading can share
|
|
34
|
+
the canvas with placed regions without carrying a class.
|
|
35
|
+
|
|
36
|
+
```html demo
|
|
37
|
+
<div class="column-layout">
|
|
38
|
+
<h3>Full canvas — no class needed</h3>
|
|
39
|
+
<div class="column-span-4 card">4</div>
|
|
40
|
+
<div class="column-span-4 card">4</div>
|
|
41
|
+
<div class="column-span-4 card">4</div>
|
|
42
|
+
</div>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Regions that do not fit wrap to the next row, as any grid does. Two
|
|
46
|
+
`.column-span-8` regions need sixteen units, so the second moves down.
|
|
47
|
+
|
|
48
|
+
## Starts
|
|
49
|
+
|
|
50
|
+
A start declares the line a region begins on. This replaces margin-based
|
|
51
|
+
offsets and is direction-independent: line 1 is the inline start, so the
|
|
52
|
+
placement flips with `dir="rtl"` on its own.
|
|
53
|
+
|
|
54
|
+
```html demo
|
|
55
|
+
<div class="column-layout">
|
|
56
|
+
<article class="column-span-10 column-start-2 card">
|
|
57
|
+
Columns 2 through 11
|
|
58
|
+
</article>
|
|
59
|
+
</div>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Used without a span, a start runs to the end of the canvas.
|
|
63
|
+
|
|
64
|
+
```html demo
|
|
65
|
+
<div class="column-layout">
|
|
66
|
+
<aside class="column-start-9 card">Columns 9 through 12</aside>
|
|
67
|
+
</div>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Keep a combined placement inside the canvas: `S + N - 1 <= 12`. So
|
|
71
|
+
`.column-start-9 .column-span-4` is valid and `.column-start-10 .column-span-4`
|
|
72
|
+
is not. Exceeding the canvas adds a thirteenth, content-sized column, and every
|
|
73
|
+
other region shrinks with it — the failure is canvas-wide, not local to the
|
|
74
|
+
region you got wrong.
|
|
75
|
+
|
|
76
|
+
## Cross-section alignment
|
|
77
|
+
|
|
78
|
+
The canvas is shared across sibling sections, so regions in different sections
|
|
79
|
+
can line up on the same columns — something a collection or a sidebar cannot
|
|
80
|
+
guarantee. This is the case no other primitive can replace.
|
|
81
|
+
|
|
82
|
+
```html demo
|
|
83
|
+
<div class="stack">
|
|
84
|
+
<div class="column-layout">
|
|
85
|
+
<h3 class="column-span-8 column-start-3">Feature title</h3>
|
|
86
|
+
<p class="muted column-span-8 column-start-3">Kicker aligned to the same line.</p>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div class="column-layout">
|
|
90
|
+
<p class="column-span-8 column-start-3">
|
|
91
|
+
Body copy starts on the same column as the title above and spans the same
|
|
92
|
+
eight columns.
|
|
93
|
+
</p>
|
|
94
|
+
<aside class="column-span-2 column-start-11 card">Inline note</aside>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Both sections name the same `column-start-3` / `column-span-8`, so their content
|
|
100
|
+
shares a left edge and an alignment gutter without a wrapping grid.
|
|
101
|
+
|
|
102
|
+
## The responsive contract
|
|
103
|
+
|
|
104
|
+
`.column-layout` has **no automatic collapse**. The canvas stays twelve columns
|
|
105
|
+
at every width, and the application owns narrow-container behavior.
|
|
106
|
+
|
|
107
|
+
This is deliberate. `8 + 4` and `3 + 9` do not become unusable at the same
|
|
108
|
+
width, a centered article may only need wider gutters, and a dashboard may want
|
|
109
|
+
three regions to become two before stacking. A single framework threshold would
|
|
110
|
+
be wrong more often than right, and a hidden one would have to be undone rather
|
|
111
|
+
than extended.
|
|
112
|
+
|
|
113
|
+
The simplest recomposition stacks everything:
|
|
114
|
+
|
|
115
|
+
```css
|
|
116
|
+
@container (width < 40rem) {
|
|
117
|
+
.profile-layout > * {
|
|
118
|
+
grid-column: 1 / -1;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
A coordinate system is more useful when you keep it through an intermediate
|
|
124
|
+
state:
|
|
125
|
+
|
|
126
|
+
```css
|
|
127
|
+
@container (width < 48rem) {
|
|
128
|
+
.profile-main {
|
|
129
|
+
grid-column: 1 / span 6;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.profile-aside {
|
|
133
|
+
grid-column: 7 / span 6;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@container (width < 32rem) {
|
|
138
|
+
.profile-main,
|
|
139
|
+
.profile-aside {
|
|
140
|
+
grid-column: 1 / -1;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```html
|
|
146
|
+
<div class="container-query">
|
|
147
|
+
<div class="column-layout profile-layout">
|
|
148
|
+
<main class="column-span-8 profile-main">...</main>
|
|
149
|
+
<aside class="column-span-4 column-start-9 profile-aside">...</aside>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The `.container-query` wrapper here enables **your** `@container` rules, not a
|
|
155
|
+
hidden framework behavior. Remove your rules and the wrapper stops mattering.
|
|
156
|
+
This is the opposite of a primitive whose responsive contract depends on a
|
|
157
|
+
wrapper someone else has to remember.
|
|
158
|
+
|
|
159
|
+
Placement classes carry zero specificity, so a single-class rule of your own
|
|
160
|
+
wins without `!important` and without having to undo a framework declaration
|
|
161
|
+
first.
|
|
162
|
+
|
|
163
|
+
## Narrow containers
|
|
164
|
+
|
|
165
|
+
Twelve columns is a wide-context tool. With the default `--gap`, a 279px
|
|
166
|
+
container spends 132px on its eleven gaps and leaves about 12px per unit — a
|
|
167
|
+
`.column-span-4` region is 84px wide.
|
|
168
|
+
|
|
169
|
+
The framework guarantees the canvas itself never overflows its container: the
|
|
170
|
+
tracks are `minmax(0, 1fr)` and every child gets `min-inline-size: 0`, so item
|
|
171
|
+
boxes stay inside their tracks. It does not guarantee that content inside a
|
|
172
|
+
narrow span stays readable, or that an unbreakable word will not paint outside
|
|
173
|
+
its track. Define a narrow representation where the composition needs one.
|
|
174
|
+
|
|
175
|
+
## Scope
|
|
176
|
+
|
|
177
|
+
The primitive is horizontal only. There are no `.row-span-*`, `.area-*`, or
|
|
178
|
+
`.order-*` classes, and no breakpoint variants such as `md-column-span-6` —
|
|
179
|
+
those would move responsive strategy back into markup. For genuinely
|
|
180
|
+
two-dimensional placement, use CSS Grid directly on your own class:
|
|
181
|
+
|
|
182
|
+
```css
|
|
183
|
+
.dashboard-summary {
|
|
184
|
+
grid-row: 1 / span 2;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The column count is fixed at twelve and is not configurable. Twelve is what
|
|
189
|
+
makes the vocabulary shared and lets `6 + 6`, `4 + 4 + 4`, `3 + 3 + 3 + 3`,
|
|
190
|
+
`8 + 4`, and `2 + 8 + 2` all land on the same canvas. For a track system whose
|
|
191
|
+
sizes carry meaning rather than twelve interchangeable units, use
|
|
192
|
+
`--grid-columns` on `.grid`.
|
|
193
|
+
|
|
194
|
+
Unlike `.grid-N`, the track template does not read `--gap`, so the gap
|
|
195
|
+
utilities are exact here at every width.
|
|
196
|
+
|
|
197
|
+
A region carrying a placement class must generate a box. `display: contents`
|
|
198
|
+
removes that box and promotes its descendants to grid items, which leaves the
|
|
199
|
+
placement with nothing to apply to.
|
|
200
|
+
|
|
201
|
+
### Classes
|
|
202
|
+
|
|
203
|
+
- `.column-layout` establishes the twelve-column canvas.
|
|
204
|
+
- `.column-span-1` … `.column-span-12` set the width in canvas units.
|
|
205
|
+
- `.column-start-1` … `.column-start-12` set the starting line, running to the
|
|
206
|
+
canvas end unless a span refines it.
|
|
@@ -27,4 +27,9 @@ Use local variables for common ratios.
|
|
|
27
27
|
.avatar-preview {
|
|
28
28
|
--frame-ratio: 1;
|
|
29
29
|
}
|
|
30
|
-
```
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`overflow: hidden` is what makes the frame a media frame: it clips the media to
|
|
33
|
+
the ratio and its corners. Floating decorations (badges, live dots, captions
|
|
34
|
+
that overhang) therefore cannot live inside the frame — they are clipped too.
|
|
35
|
+
Place them in a sibling or wrapper around the frame instead.
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
# Grid
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Two contracts sit behind these classes. Pick by asking what determines the
|
|
4
|
+
column count.
|
|
5
|
+
|
|
6
|
+
- The **item width** is what matters — use `.grid` and tune `--grid-min`.
|
|
7
|
+
- The **column density** is what matters — use `.grid-2`, `.grid-3`, `.grid-4`,
|
|
8
|
+
or `.grid-6`.
|
|
9
|
+
|
|
10
|
+
## Space-driven collection
|
|
11
|
+
|
|
12
|
+
`.grid` fits as many columns as the available inline space permits. Incomplete
|
|
13
|
+
final rows are part of the contract.
|
|
4
14
|
|
|
5
15
|
```html demo
|
|
6
16
|
<section class="grid">
|
|
7
|
-
<article class="card">
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
</article>
|
|
11
|
-
<article class="card">
|
|
12
|
-
<h3>Team</h3>
|
|
13
|
-
<p>For shared products.</p>
|
|
14
|
-
</article>
|
|
15
|
-
<article class="card">
|
|
16
|
-
<h3>Scale</h3>
|
|
17
|
-
<p>For larger systems.</p>
|
|
18
|
-
</article>
|
|
17
|
+
<article class="card"><h3>Starter</h3><p>For small projects.</p></article>
|
|
18
|
+
<article class="card"><h3>Team</h3><p>For shared products.</p></article>
|
|
19
|
+
<article class="card"><h3>Scale</h3><p>For larger systems.</p></article>
|
|
19
20
|
</section>
|
|
20
21
|
```
|
|
21
22
|
|
|
22
|
-
Tune the
|
|
23
|
+
Tune the item minimum with `--grid-min`.
|
|
23
24
|
|
|
24
25
|
```css
|
|
25
26
|
.pricing-grid {
|
|
@@ -27,116 +28,113 @@ Tune the minimum item width with `--grid-min`.
|
|
|
27
28
|
}
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
custom or asymmetric layout. Because this overrides the intrinsic
|
|
32
|
-
`auto-fit/minmax` algorithm, you own any narrow-container collapse:
|
|
31
|
+
## Count-driven density
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
33
|
+
`.grid-N` declares a structural density of N columns. It is responsive on its
|
|
34
|
+
own: it never exceeds N columns, never overflows, and every item keeps the same
|
|
35
|
+
width.
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
```html demo
|
|
38
|
+
<div class="grid-4">
|
|
39
|
+
<div class="card">Exercitation</div>
|
|
40
|
+
<div class="card">Amet mollit</div>
|
|
41
|
+
<div class="card">Aute cillum</div>
|
|
42
|
+
<div class="card">Duis non </div>
|
|
43
|
+
</div>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
`--grid-
|
|
47
|
-
|
|
46
|
+
`--grid-min` does not apply here. Item width is `.grid`'s contract; column
|
|
47
|
+
density is `.grid-N`'s. Choose the preset that suits your item size:
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
| Item | Preset |
|
|
50
|
+
|-----------------------------------|----------------------|
|
|
51
|
+
| large card | `.grid-2` |
|
|
52
|
+
| card with a heading and a summary | `.grid-3`, `.grid-4` |
|
|
53
|
+
| compact tile, stat, avatar | `.grid-6` |
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
## Balanced subdivision
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
Left alone, a preset collapses one column at a time, so a six-item `.grid-6`
|
|
58
|
+
can pass through five columns — five items and a lone sixth. Wrap it in
|
|
59
|
+
`.container-query` and it only ever enters a **divisor of N**:
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
```text
|
|
62
|
+
.grid-2 2 → 1
|
|
63
|
+
.grid-3 3 → 1
|
|
64
|
+
.grid-4 4 → 2 → 1
|
|
65
|
+
.grid-6 6 → 3 → 2 → 1
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Every state splits the collection evenly, and all items keep the same width.
|
|
56
69
|
|
|
57
70
|
```html demo
|
|
58
71
|
<div class="container-query">
|
|
59
|
-
<div class="grid-
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
</
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
<p>For shared products.</p>
|
|
67
|
-
</article>
|
|
68
|
-
<article class="card">
|
|
69
|
-
<h3>Scale</h3>
|
|
70
|
-
<p>For larger systems.</p>
|
|
71
|
-
</article>
|
|
72
|
+
<div class="grid-6">
|
|
73
|
+
<div class="card">1</div>
|
|
74
|
+
<div class="card">2</div>
|
|
75
|
+
<div class="card">3</div>
|
|
76
|
+
<div class="card">4</div>
|
|
77
|
+
<div class="card">5</div>
|
|
78
|
+
<div class="card">6</div>
|
|
72
79
|
</div>
|
|
73
80
|
</div>
|
|
74
81
|
```
|
|
75
82
|
|
|
76
|
-
|
|
83
|
+
The wrapper is an opt-in for precision, never a prerequisite for responsive
|
|
84
|
+
behavior — forgetting it costs you the exact chain, nothing else. It has to be
|
|
85
|
+
an ancestor: an element cannot query its own size without taking inline-size
|
|
86
|
+
containment, which would collapse the grid inside a `.cluster`, a float, or any
|
|
87
|
+
shrink-to-fit box. Put `.container-query` on a normal block-level wrapper for
|
|
88
|
+
the same reason.
|
|
77
89
|
|
|
78
|
-
|
|
90
|
+
The chain balances the **declared density**, not your actual item count. Eight
|
|
91
|
+
items in `.grid-6` still give `6 + 2`. For a paginated collection, choose a page
|
|
92
|
+
size that suits the density — 12, 20, and 24 divide well. A partial final page
|
|
93
|
+
is normal.
|
|
94
|
+
|
|
95
|
+
## Exact templates
|
|
96
|
+
|
|
97
|
+
`--grid-columns` replaces `.grid`'s intrinsic recipe. Use it for exact track
|
|
98
|
+
templates that do not match a built-in layout contract: arbitrary structural
|
|
99
|
+
counts such as seven calendar days, asymmetric fractional tracks, or mixed
|
|
100
|
+
intrinsic/flexible tracks. Once set, the application owns narrow-container
|
|
101
|
+
behavior.
|
|
102
|
+
|
|
103
|
+
```css
|
|
104
|
+
/* Semantic count not represented by .grid-N */
|
|
105
|
+
--grid-columns: repeat(7, minmax(0, 1fr));
|
|
106
|
+
|
|
107
|
+
/* Meaningful asymmetric ratio */
|
|
108
|
+
--grid-columns: 2fr 1fr 1fr 1fr;
|
|
109
|
+
|
|
110
|
+
/* Intrinsic trailing control */
|
|
111
|
+
--grid-columns: repeat(4, minmax(0, 1fr)) auto;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```html
|
|
79
115
|
<div class="container-query">
|
|
80
|
-
<div class="grid
|
|
81
|
-
<article class="card">
|
|
82
|
-
<h3>Starter</h3>
|
|
83
|
-
<p>For small projects.</p>
|
|
84
|
-
</article>
|
|
85
|
-
<article class="card">
|
|
86
|
-
<h3>Team</h3>
|
|
87
|
-
<p>For shared products.</p>
|
|
88
|
-
</article>
|
|
89
|
-
<article class="card">
|
|
90
|
-
<h3>Scale</h3>
|
|
91
|
-
<p>For larger systems.</p>
|
|
92
|
-
</article>
|
|
93
|
-
<article class="card">
|
|
94
|
-
<h3>Enterprise</h3>
|
|
95
|
-
<p>Contact us.</p>
|
|
96
|
-
</article>
|
|
97
|
-
</div>
|
|
116
|
+
<div class="editorial-grid grid">...</div>
|
|
98
117
|
</div>
|
|
99
118
|
```
|
|
100
119
|
|
|
101
|
-
|
|
120
|
+
```css
|
|
121
|
+
.editorial-grid {
|
|
122
|
+
--grid-columns: minmax(0, 2fr) minmax(0, 1fr);
|
|
123
|
+
}
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<strong>18</strong>
|
|
109
|
-
</article>
|
|
110
|
-
<article class="card compact">
|
|
111
|
-
<span class="muted">Queued</span>
|
|
112
|
-
<strong>7</strong>
|
|
113
|
-
</article>
|
|
114
|
-
<article class="card compact">
|
|
115
|
-
<span class="muted">Blocked</span>
|
|
116
|
-
<strong>2</strong>
|
|
117
|
-
</article>
|
|
118
|
-
<article class="card compact">
|
|
119
|
-
<span class="muted">Shipped</span>
|
|
120
|
-
<strong>41</strong>
|
|
121
|
-
</article>
|
|
122
|
-
<article class="card compact">
|
|
123
|
-
<span class="muted">Owners</span>
|
|
124
|
-
<strong>6</strong>
|
|
125
|
-
</article>
|
|
126
|
-
<article class="card compact">
|
|
127
|
-
<span class="muted">SLA</span>
|
|
128
|
-
<strong>99%</strong>
|
|
129
|
-
</article>
|
|
130
|
-
</div>
|
|
131
|
-
</div>
|
|
125
|
+
@container (width < 40rem) {
|
|
126
|
+
.editorial-grid {
|
|
127
|
+
--grid-columns: 1fr;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
132
130
|
```
|
|
133
131
|
|
|
134
|
-
|
|
132
|
+
For an ordinary main region plus an aside, prefer `.sidebar-layout`. When a
|
|
133
|
+
small group of peer regions must be either entirely horizontal or entirely
|
|
134
|
+
stacked, prefer `.switcher`.
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
- With `.container-query`: `.grid-2`, `.grid-3`, and `.grid-4` collapse to one column on a narrow wrapper (under 28rem). `.grid-3` and `.grid-4` step through 2 columns between 28rem and 48rem. `.grid-6` starts at 2 columns under 28rem, steps through 3 columns between 28rem and 64rem, then returns to 6 columns.
|
|
138
|
-
- The intermediate 2-col step is useful for lists of items divisible by both 2 and 3 (or 4) — a 12-item list reads as 12 lines, then 6 lines of 2, then 4 lines of 3 (or 3 lines of 4), depending on the grid.
|
|
139
|
-
- `.grid-6` is for compact items such as stats, shortcut tiles, swatches, avatar summaries, and small settings cards. It does not collapse to one column by default. If item width matters more than an exact six-column rhythm, prefer `.grid` with a smaller `--grid-min`.
|
|
140
|
-
- The wrapper is the query container, so the same class behaves differently in a narrow sidebar than in a wide main area. No viewport breakpoints are involved.
|
|
136
|
+
### Hooks
|
|
141
137
|
|
|
142
|
-
|
|
138
|
+
- `--grid-min` tunes the minimum item width of the intrinsic `.grid` recipe.
|
|
139
|
+
It does not apply to `.grid-N`.
|
|
140
|
+
- `--grid-columns` replaces that recipe with an author-owned template.
|
|
@@ -25,4 +25,4 @@ Add `.items-center` to align the leading element with short trailing content. Fo
|
|
|
25
25
|
</div>
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
The media object is the underlying pattern of `.blog-author`, `.blog-comment`, and similar compositions in templates. Components can adopt it instead of repeating the grid rule.
|
|
28
|
+
The media object is the underlying pattern of `.blog-author`, `.blog-comment`, and similar compositions in templates. Components can adopt it instead of repeating the grid rule.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Layout Overview
|
|
2
2
|
|
|
3
|
-
Layout provides a small set of composable building blocks for common page, app, and content structure. It is not a utility-first framework and it is
|
|
3
|
+
Layout provides a small set of composable building blocks for common page, app, and content structure. It is not a utility-first framework, and the twelve-column canvas it does ship (`.column-layout`) is an opt-in vocabulary for deliberate composition rather than the default way to build a page.
|
|
4
4
|
|
|
5
5
|
- Layout classes compose components; components do not own page spacing.
|
|
6
6
|
- Use custom properties to tune a layout instance.
|
|
@@ -8,6 +8,19 @@ Layout provides a small set of composable building blocks for common page, app,
|
|
|
8
8
|
- Keep class names semantic enough to remember and generic enough to reuse.
|
|
9
9
|
- Add a new layout primitive only when a pattern appears often and is awkward to express with existing primitives.
|
|
10
10
|
|
|
11
|
+
See [Choosing a layout](./choosing.md) for the distinctions between responsive
|
|
12
|
+
collections, fixed structural grids, all-or-nothing peer regions, sidebars, and
|
|
13
|
+
explicit column placement.
|
|
14
|
+
|
|
15
|
+
## Child contract
|
|
16
|
+
|
|
17
|
+
Layout primitives operate on the boxes generated by their direct children.
|
|
18
|
+
Applying `display: contents` to a participating child removes that box and
|
|
19
|
+
promotes its descendants into the parent layout, bypassing the sizing or
|
|
20
|
+
placement assigned to the child. The layout contracts below are expressed
|
|
21
|
+
against direct children — keep those children as real boxes unless you intend
|
|
22
|
+
that bypass.
|
|
23
|
+
|
|
11
24
|
## Spacing tokens
|
|
12
25
|
|
|
13
26
|
Layout shares the global spacing surface and exposes a small set of gap and rhythm tokens.
|
|
@@ -34,4 +47,4 @@ Most layout primitives read `--gap` and allow local overrides.
|
|
|
34
47
|
|
|
35
48
|
Prefer a local custom property over adding many one-off utility classes. Use inline styles only for demos, prototypes, or truly dynamic values.
|
|
36
49
|
|
|
37
|
-
There are no `.gap-sm` / `.gap-md` / `.gap-lg` density variants on the core layout primitives; set `--gap` locally when only spacing should change. The
|
|
50
|
+
There are no `.gap-sm` / `.gap-md` / `.gap-lg` density variants on the core layout primitives; set `--gap` locally when only spacing should change. The extra utilities (`src/css/utilities/extra.css`) ship those gap utilities for row/column containers.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Horizontal rails that stay useful without JavaScript and snap in modern browsers.
|
|
4
4
|
|
|
5
|
-
> **
|
|
5
|
+
> **Module** — import `actual-css/css/layout/scroll-snap` or `actual-css/css/layout`.
|
|
6
6
|
|
|
7
7
|
Use `.scroll-snap` for a niche row of items that should scroll horizontally, such as card rails, media strips, overflow tabs, or a simple touch-friendly carousel baseline. Scrolling only appears when the items are wider than the container; set `--scroll-snap-item-size` for card rails.
|
|
8
8
|
|
|
@@ -51,4 +51,4 @@ Keep scrollbars visible by default. If a product deliberately hides them, make t
|
|
|
51
51
|
</div>
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
`.scroll-snap` is not a full interactive carousel. For previous/next controls, pagination, active state, mouse drag, looping, autoplay, or robust accessibility behavior, use a dedicated carousel library such as Swiper and compose it with Actual components.
|
|
54
|
+
`.scroll-snap` is not a full interactive carousel. For previous/next controls, pagination, active state, mouse drag, looping, autoplay, or robust accessibility behavior, use a dedicated carousel library such as Swiper and compose it with Actual components.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Scroll Target
|
|
2
|
+
|
|
3
|
+
Anchor scroll offset: keep `#hash` and `scrollIntoView()` targets clear of sticky headers.
|
|
4
|
+
|
|
5
|
+
> **Module** — import `actual-css/css/layout/scroll-target` or `actual-css/css/layout`.
|
|
6
|
+
|
|
7
|
+
A hash link or scripted scroll places the target flush at the scroll container's start edge. Under a sticky header such as `.topbar`, the heading you jumped to lands underneath it. Add `.scroll-target` to the elements that are link targets — sections, headings — and the browser stops early, reserving space above them.
|
|
8
|
+
|
|
9
|
+
```html demo
|
|
10
|
+
<nav class="cluster" aria-label="Sections" style="margin-block-end: var(--space-30)">
|
|
11
|
+
<a class="btn neutral sm" href="#st-alpha">Alpha</a>
|
|
12
|
+
<a class="btn neutral sm" href="#st-beta">Beta</a>
|
|
13
|
+
<a class="btn neutral sm" href="#st-gamma">Gamma</a>
|
|
14
|
+
</nav>
|
|
15
|
+
<div class="overflow-auto" style="block-size: 10rem; border: var(--border-width) solid var(--border); border-radius: var(--radius)">
|
|
16
|
+
<section id="st-alpha" class="scroll-target" style="padding: var(--space-30)">
|
|
17
|
+
<h3>Alpha</h3>
|
|
18
|
+
<p>The first section. Followed by enough content to make the container scroll.</p>
|
|
19
|
+
</section>
|
|
20
|
+
<section id="st-beta" class="scroll-target" style="padding: var(--space-30)">
|
|
21
|
+
<h3>Beta</h3>
|
|
22
|
+
<p>The second section. Its top edge stops below the container edge.</p>
|
|
23
|
+
</section>
|
|
24
|
+
<section id="st-gamma" class="scroll-target" style="padding: var(--space-30)">
|
|
25
|
+
<h3>Gamma</h3>
|
|
26
|
+
<p>The last section.</p>
|
|
27
|
+
</section>
|
|
28
|
+
</div>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The offset is a plain `scroll-margin-block-start`, so it works in every scroll container — the viewport, a sidebar, an overflow region — and composes with the scrollspy enhancer. Scrollspy only decides which link is active; this offset decides where the page actually lands when the link is followed.
|
|
32
|
+
|
|
33
|
+
## CSS hooks
|
|
34
|
+
|
|
35
|
+
- `--scroll-target-offset` — space kept above the target after scrolling. Set it
|
|
36
|
+
once on `:root` (or on the sticky header's height) in applications with a
|
|
37
|
+
fixed header:
|
|
38
|
+
|
|
39
|
+
```css
|
|
40
|
+
:root {
|
|
41
|
+
--scroll-target-offset: 5rem;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Deliberately no `[id]` global rule: making the offset explicit per target keeps plain ids (modals, form fields, skip links) untouched.
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
# Sidebar Layout
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Wrap it in `.container-query` to make the switch depend on the container width. Below 64rem the columns stack; at and above it the aside takes `--sidebar-layout-size` and the content takes the remaining space. Older browsers use the viewport fallback.
|
|
3
|
+
Use `.sidebar-layout` for a main region followed by a secondary region. It
|
|
4
|
+
switches intrinsically according to its own available width: the regions sit
|
|
5
|
+
side by side when the main minimum, preferred aside width, and gap fit; they
|
|
6
|
+
otherwise stack. No `.container-query` ancestor is required.
|
|
8
7
|
|
|
9
8
|
```html demo
|
|
10
|
-
<div class="
|
|
11
|
-
<
|
|
12
|
-
<article
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
</article>
|
|
9
|
+
<div class="sidebar-layout">
|
|
10
|
+
<article class="stack">
|
|
11
|
+
<h1>Long-form article</h1>
|
|
12
|
+
<p>Article body that benefits from a related table of contents.</p>
|
|
13
|
+
</article>
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
</ol>
|
|
22
|
-
</aside>
|
|
23
|
-
</div>
|
|
15
|
+
<aside class="stack">
|
|
16
|
+
<h3>On this page</h3>
|
|
17
|
+
<ol class="list-reset"><li><a class="link-muted" href="#">Section</a></li></ol>
|
|
18
|
+
</aside>
|
|
24
19
|
</div>
|
|
25
20
|
```
|
|
26
21
|
|
|
27
|
-
|
|
22
|
+
The first child is the flexible main region and the last child is the aside.
|
|
23
|
+
Use a custom `.grid` template only when an exact editorial ratio is structural.
|
|
24
|
+
|
|
25
|
+
### Hooks
|
|
26
|
+
|
|
27
|
+
- `--sidebar-layout-size` sets the aside's preferred width.
|
|
28
|
+
- `--sidebar-content-min` sets the main region's minimum viable width.
|