@astuteo/breakout-grid 5.1.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/LICENSE +21 -0
- package/README.md +223 -0
- package/breakout-grid-visualizer-lite.js +659 -0
- package/breakout-grid-visualizer.js +2523 -0
- package/craft-integration.twig +58 -0
- package/dist/_objects.breakout-grid.css +656 -0
- package/package.json +65 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Breakout Grid - Objects Layer (ITCSS)
|
|
3
|
+
* Version: 5.1.0
|
|
4
|
+
*
|
|
5
|
+
* Documentation: https://github.com/astuteo-llc/breakout-grid
|
|
6
|
+
*
|
|
7
|
+
* ============================================================================
|
|
8
|
+
* TABLE OF CONTENTS
|
|
9
|
+
* ============================================================================
|
|
10
|
+
*
|
|
11
|
+
* CONFIGURATION
|
|
12
|
+
* - Configuration Variables ........... Customizable :root variables
|
|
13
|
+
* - Computed Values ................... Auto-calculated (do not edit)
|
|
14
|
+
*
|
|
15
|
+
* GRID CONTAINERS
|
|
16
|
+
* - Grid Container - Main ............. .grid-cols-breakout
|
|
17
|
+
* - Subgrid ........................... .grid-cols-breakout-subgrid
|
|
18
|
+
* - Left/Right Aligned Variants ....... .grid-cols-{area}-{left|right}
|
|
19
|
+
* - Breakout Modifiers ................ .breakout-to-{content|popout|feature}
|
|
20
|
+
* - Breakout None ..................... .breakout-none, .breakout-none-flex
|
|
21
|
+
*
|
|
22
|
+
* COLUMN UTILITIES
|
|
23
|
+
* - Basic ............................. .col-{full|feature|popout|content|center}
|
|
24
|
+
* - Start/End ......................... .col-start-*, .col-end-*
|
|
25
|
+
* - Left/Right Spans .................. .col-*-left, .col-*-right
|
|
26
|
+
* - Advanced Spans .................... .col-*-to-*
|
|
27
|
+
* - Full Limit ........................ .col-full-limit
|
|
28
|
+
*
|
|
29
|
+
* SPACING UTILITIES
|
|
30
|
+
* - Padding ........................... .p-breakout, .p-gap, .p-*-to-content
|
|
31
|
+
* - Margins ........................... .m-breakout, .m-gap, .-m-*
|
|
32
|
+
*
|
|
33
|
+
* ============================================================================
|
|
34
|
+
* INTEGRATION (ITCSS + Tailwind v4)
|
|
35
|
+
* ============================================================================
|
|
36
|
+
*
|
|
37
|
+
* Add this file to your Objects layer. In your main CSS file:
|
|
38
|
+
*
|
|
39
|
+
* @import 'tailwindcss';
|
|
40
|
+
*
|
|
41
|
+
* @import './_settings.fonts.css';
|
|
42
|
+
* @import './_objects.breakout-grid.css'; <-- Add here (Objects layer)
|
|
43
|
+
* @import './_utilities.global.css';
|
|
44
|
+
*
|
|
45
|
+
* @layer components {
|
|
46
|
+
* @import './_components.hero.css';
|
|
47
|
+
* ...
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* ============================================================================
|
|
51
|
+
* QUICK START
|
|
52
|
+
* ============================================================================
|
|
53
|
+
*
|
|
54
|
+
* <main class="grid-cols-breakout">
|
|
55
|
+
* <article class="col-content">Reading width</article>
|
|
56
|
+
* <figure class="col-feature">Wider for images</figure>
|
|
57
|
+
* <div class="col-full">Edge to edge</div>
|
|
58
|
+
* </main>
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/* ============================================================================
|
|
63
|
+
CONFIGURATION VARIABLES
|
|
64
|
+
============================================================================
|
|
65
|
+
To restore this grid in the visualizer, copy from here to END CONFIGURATION.
|
|
66
|
+
Paste into the "Restore" dialog at:
|
|
67
|
+
https://github.com/astuteo-llc/breakout-grid
|
|
68
|
+
============================================================================ */
|
|
69
|
+
|
|
70
|
+
:root {
|
|
71
|
+
/* Content (text width) */
|
|
72
|
+
--content-min: 53rem;
|
|
73
|
+
--content-base: 75vw;
|
|
74
|
+
--content-max: 61rem;
|
|
75
|
+
|
|
76
|
+
/* Default column for children without col-* class */
|
|
77
|
+
--default-col: content;
|
|
78
|
+
|
|
79
|
+
/* Track widths */
|
|
80
|
+
--popout-width: 5rem;
|
|
81
|
+
--full-limit: 115rem;
|
|
82
|
+
|
|
83
|
+
/* Feature track */
|
|
84
|
+
--feature-min: 0rem;
|
|
85
|
+
--feature-scale: 12vw;
|
|
86
|
+
--feature-max: 12rem;
|
|
87
|
+
|
|
88
|
+
/* Outer margins */
|
|
89
|
+
--base-gap: 1rem;
|
|
90
|
+
--max-gap: 15rem;
|
|
91
|
+
|
|
92
|
+
/* Responsive scale */
|
|
93
|
+
--gap-scale-default: 4vw;
|
|
94
|
+
--gap-scale-lg: 5vw;
|
|
95
|
+
--gap-scale-xl: 6vw;
|
|
96
|
+
|
|
97
|
+
/* Breakout padding */
|
|
98
|
+
--breakout-min: 1rem;
|
|
99
|
+
--breakout-scale: 5vw;
|
|
100
|
+
|
|
101
|
+
/* Breakpoints (used in media queries below) */
|
|
102
|
+
/* --breakpoint-lg: 1024pxpx; */
|
|
103
|
+
/* --breakpoint-xl: 1280pxpx; */
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* ============================================================================
|
|
107
|
+
END CONFIGURATION
|
|
108
|
+
============================================================================ */
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
/* ============================================================================
|
|
112
|
+
COMPUTED VALUES - DO NOT EDIT
|
|
113
|
+
============================================================================
|
|
114
|
+
These are calculated from the customizable variables above.
|
|
115
|
+
Editing these directly will break the grid calculations.
|
|
116
|
+
============================================================================ */
|
|
117
|
+
|
|
118
|
+
:root {
|
|
119
|
+
/* Responsive gap: scales between base and max based on viewport */
|
|
120
|
+
--gap: clamp(var(--base-gap), var(--gap-scale-default), var(--max-gap));
|
|
121
|
+
|
|
122
|
+
/* Computed gap: larger value for full-width spacing */
|
|
123
|
+
--computed-gap: max(var(--gap), calc((100vw - var(--content)) / 10));
|
|
124
|
+
|
|
125
|
+
/* Content width: fluid between min/max, respects gap on both sides */
|
|
126
|
+
--content: min(clamp(var(--content-min), var(--content-base), var(--content-max)), 100% - var(--gap) * 2);
|
|
127
|
+
|
|
128
|
+
/* Content inset: for left/right aligned grids (single gap) */
|
|
129
|
+
--content-inset: min(clamp(var(--content-min), var(--content-base), var(--content-max)), calc(100% - var(--gap)));
|
|
130
|
+
|
|
131
|
+
/* Half content: used for center alignment */
|
|
132
|
+
--content-half: calc(var(--content) / 2);
|
|
133
|
+
|
|
134
|
+
/* Track definitions for grid-template-columns */
|
|
135
|
+
--full: minmax(var(--gap), 1fr);
|
|
136
|
+
--feature: minmax(0, clamp(var(--feature-min), var(--feature-scale), var(--feature-max)));
|
|
137
|
+
--popout: minmax(0, var(--popout-width));
|
|
138
|
+
|
|
139
|
+
/* Alignment padding: for aligning content inside wider columns */
|
|
140
|
+
--breakout-padding: clamp(var(--breakout-min), var(--breakout-scale), var(--popout-width));
|
|
141
|
+
--popout-to-content: clamp(var(--breakout-min), var(--breakout-scale), var(--popout-width));
|
|
142
|
+
--feature-to-content: calc(clamp(var(--feature-min), var(--feature-scale), var(--feature-max)) + var(--popout-width));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* Responsive gap scaling */
|
|
146
|
+
@media (min-width: 1024pxpx) {
|
|
147
|
+
:root {
|
|
148
|
+
--gap: clamp(var(--base-gap), var(--gap-scale-lg), var(--max-gap));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@media (min-width: 1280pxpx) {
|
|
153
|
+
:root {
|
|
154
|
+
--gap: clamp(var(--base-gap), var(--gap-scale-xl), var(--max-gap));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* ========================================
|
|
159
|
+
Grid Container - Main
|
|
160
|
+
========================================
|
|
161
|
+
|
|
162
|
+
The primary grid container. Apply to any element that should use
|
|
163
|
+
the breakout grid system. All direct children default to the
|
|
164
|
+
content column unless given a col-* class.
|
|
165
|
+
|
|
166
|
+
Basic usage:
|
|
167
|
+
<main class="grid-cols-breakout">
|
|
168
|
+
<article>Default content width</article>
|
|
169
|
+
<figure class="col-feature">Wider for images</figure>
|
|
170
|
+
<div class="col-full">Edge to edge</div>
|
|
171
|
+
</main>
|
|
172
|
+
*/
|
|
173
|
+
.grid-cols-breakout {
|
|
174
|
+
display: grid;
|
|
175
|
+
grid-template-columns:
|
|
176
|
+
[full-start] var(--full)
|
|
177
|
+
[feature-start] var(--feature)
|
|
178
|
+
[popout-start] var(--popout)
|
|
179
|
+
[content-start] var(--content-half) [center-start center-end] var(--content-half) [content-end]
|
|
180
|
+
var(--popout) [popout-end]
|
|
181
|
+
var(--feature) [feature-end]
|
|
182
|
+
var(--full) [full-end];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Default column for direct children without explicit col-* class */
|
|
186
|
+
[class*='grid-cols-breakout'] > *:not([class*='col-']),
|
|
187
|
+
[class*='grid-cols-feature'] > *:not([class*='col-']),
|
|
188
|
+
[class*='grid-cols-popout'] > *:not([class*='col-']),
|
|
189
|
+
[class*='grid-cols-content'] > *:not([class*='col-']) {
|
|
190
|
+
grid-column: var(--default-col, content);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* ----------------------------------------
|
|
194
|
+
Subgrid - Nested Alignment
|
|
195
|
+
----------------------------------------
|
|
196
|
+
|
|
197
|
+
Use subgrid when you need children of a spanning element to align
|
|
198
|
+
with the parent grid's tracks. The child inherits the parent's
|
|
199
|
+
column lines.
|
|
200
|
+
|
|
201
|
+
Example - Card grid inside a feature-width container:
|
|
202
|
+
<div class="col-feature grid-cols-breakout-subgrid">
|
|
203
|
+
<h2 class="col-content">Title aligns with content</h2>
|
|
204
|
+
<div class="col-feature">Full width of parent</div>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
Browser support: ~93% (check caniuse.com/css-subgrid)
|
|
208
|
+
*/
|
|
209
|
+
.grid-cols-breakout-subgrid {
|
|
210
|
+
display: grid;
|
|
211
|
+
grid-template-columns: subgrid;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* ========================================
|
|
215
|
+
Grid Container - Left/Right Aligned Variants
|
|
216
|
+
========================================
|
|
217
|
+
|
|
218
|
+
Use these when content should anchor to one side instead of centering.
|
|
219
|
+
Common for asymmetric layouts, sidebars, or split-screen designs.
|
|
220
|
+
|
|
221
|
+
Left variants: Content anchors to left edge, right side has outer tracks
|
|
222
|
+
Right variants: Content anchors to right edge, left side has outer tracks
|
|
223
|
+
|
|
224
|
+
Example - Image left, text right:
|
|
225
|
+
<section class="grid-cols-feature-left">
|
|
226
|
+
<figure class="col-feature">Image anchored left</figure>
|
|
227
|
+
<div class="col-content">Text in content area</div>
|
|
228
|
+
</section>
|
|
229
|
+
|
|
230
|
+
Example - Sidebar layout:
|
|
231
|
+
<div class="grid-cols-content-right">
|
|
232
|
+
<aside class="col-full">Sidebar fills left</aside>
|
|
233
|
+
<main class="col-content">Main content right-aligned</main>
|
|
234
|
+
</div>
|
|
235
|
+
*/
|
|
236
|
+
.grid-cols-feature-left {
|
|
237
|
+
display: grid;
|
|
238
|
+
grid-template-columns:
|
|
239
|
+
[full-start] var(--full)
|
|
240
|
+
[feature-start] var(--feature)
|
|
241
|
+
[popout-start] var(--popout)
|
|
242
|
+
[content-start] var(--content-inset) [content-end]
|
|
243
|
+
var(--popout) [popout-end]
|
|
244
|
+
var(--feature) [feature-end full-end];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.grid-cols-popout-left {
|
|
248
|
+
display: grid;
|
|
249
|
+
grid-template-columns:
|
|
250
|
+
[full-start] var(--full)
|
|
251
|
+
[feature-start] var(--feature)
|
|
252
|
+
[popout-start] var(--popout)
|
|
253
|
+
[content-start] var(--content-inset) [content-end]
|
|
254
|
+
var(--popout) [popout-end full-end];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.grid-cols-content-left {
|
|
258
|
+
display: grid;
|
|
259
|
+
grid-template-columns:
|
|
260
|
+
[full-start] var(--full)
|
|
261
|
+
[feature-start] var(--feature)
|
|
262
|
+
[popout-start] var(--popout)
|
|
263
|
+
[content-start] var(--content-inset) [content-end full-end];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* ========================================
|
|
267
|
+
Grid Container - Right Aligned Variants
|
|
268
|
+
======================================== */
|
|
269
|
+
.grid-cols-feature-right {
|
|
270
|
+
display: grid;
|
|
271
|
+
grid-template-columns:
|
|
272
|
+
[full-start feature-start] var(--feature)
|
|
273
|
+
[popout-start] var(--popout)
|
|
274
|
+
[content-start] var(--content-inset) [content-end]
|
|
275
|
+
var(--popout) [popout-end]
|
|
276
|
+
var(--feature) [feature-end]
|
|
277
|
+
var(--full) [full-end];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.grid-cols-popout-right {
|
|
281
|
+
display: grid;
|
|
282
|
+
grid-template-columns:
|
|
283
|
+
[full-start popout-start] var(--popout)
|
|
284
|
+
[content-start] var(--content-inset) [content-end]
|
|
285
|
+
var(--popout) [popout-end]
|
|
286
|
+
var(--feature) [feature-end]
|
|
287
|
+
var(--full) [full-end];
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.grid-cols-content-right {
|
|
291
|
+
display: grid;
|
|
292
|
+
grid-template-columns:
|
|
293
|
+
[full-start content-start] var(--content-inset) [content-end]
|
|
294
|
+
var(--popout) [popout-end]
|
|
295
|
+
var(--feature) [feature-end]
|
|
296
|
+
var(--full) [full-end];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* ========================================
|
|
300
|
+
Breakout Modifiers (for nested grids)
|
|
301
|
+
========================================
|
|
302
|
+
|
|
303
|
+
When you nest a grid inside another element (like inside col-feature),
|
|
304
|
+
the nested grid doesn't know about the parent's constraints. Use these
|
|
305
|
+
modifiers to "reset" the grid to fit its container.
|
|
306
|
+
|
|
307
|
+
breakout-to-content: Collapses all tracks - nested grid fills container
|
|
308
|
+
breakout-to-popout: Keeps popout tracks, collapses feature/full
|
|
309
|
+
breakout-to-feature: Keeps feature+popout tracks, collapses full
|
|
310
|
+
|
|
311
|
+
Example - Full-width hero with nested content grid:
|
|
312
|
+
<div class="col-full bg-blue-500">
|
|
313
|
+
<div class="grid-cols-breakout breakout-to-content">
|
|
314
|
+
<h1>This h1 fills the blue container</h1>
|
|
315
|
+
<p class="col-content">But content still works!</p>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
|
|
319
|
+
Example - Feature-width card with internal grid:
|
|
320
|
+
<article class="col-feature">
|
|
321
|
+
<div class="grid-cols-breakout breakout-to-feature">
|
|
322
|
+
<img class="col-feature">Full width of card</img>
|
|
323
|
+
<p class="col-content">Padded text inside</p>
|
|
324
|
+
</div>
|
|
325
|
+
</article>
|
|
326
|
+
*/
|
|
327
|
+
.grid-cols-breakout.breakout-to-content {
|
|
328
|
+
grid-template-columns: [full-start feature-start popout-start content-start center-start] minmax(0, 1fr) [center-end content-end popout-end feature-end full-end];
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.grid-cols-breakout.breakout-to-popout {
|
|
332
|
+
grid-template-columns: [full-start feature-start popout-start] var(--popout) [content-start center-start] minmax(0, 1fr) [center-end content-end] var(--popout) [popout-end feature-end full-end];
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.grid-cols-breakout.breakout-to-feature {
|
|
336
|
+
grid-template-columns: [full-start feature-start] var(--feature) [popout-start] var(--popout) [content-start center-start] minmax(0, 1fr) [center-end content-end] var(--popout) [popout-end] var(--feature) [feature-end full-end];
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* ----------------------------------------
|
|
340
|
+
Breakout None - Disable Grid
|
|
341
|
+
----------------------------------------
|
|
342
|
+
|
|
343
|
+
Use when you need to escape the grid entirely. Useful for:
|
|
344
|
+
- Sidebar layouts where one column shouldn't use grid
|
|
345
|
+
- Components that manage their own layout
|
|
346
|
+
- CMS blocks that shouldn't inherit grid behavior
|
|
347
|
+
|
|
348
|
+
Example - Two-column layout with sidebar:
|
|
349
|
+
<div class="grid grid-cols-[300px_1fr]">
|
|
350
|
+
<aside class="breakout-none">Sidebar - no grid here</aside>
|
|
351
|
+
<main class="grid-cols-breakout">Main content uses grid</main>
|
|
352
|
+
</div>
|
|
353
|
+
*/
|
|
354
|
+
.breakout-none { display: block; }
|
|
355
|
+
.breakout-none-flex { display: flex; }
|
|
356
|
+
.breakout-none-grid { display: grid; }
|
|
357
|
+
|
|
358
|
+
/* ========================================
|
|
359
|
+
Column Utilities - Basic
|
|
360
|
+
========================================
|
|
361
|
+
|
|
362
|
+
Place elements in specific grid tracks. These are the core utilities
|
|
363
|
+
you'll use most often.
|
|
364
|
+
|
|
365
|
+
col-full: Edge to edge (viewport width minus gap)
|
|
366
|
+
col-feature: Wide content (images, videos, heroes)
|
|
367
|
+
col-popout: Slightly wider than content (pull quotes, callouts)
|
|
368
|
+
col-content: Standard reading width (articles, text)
|
|
369
|
+
col-center: Centered within content (rare, for precise centering)
|
|
370
|
+
*/
|
|
371
|
+
.col-full { grid-column: full; }
|
|
372
|
+
.col-feature { grid-column: feature; }
|
|
373
|
+
.col-popout { grid-column: popout; }
|
|
374
|
+
.col-content { grid-column: content; }
|
|
375
|
+
.col-center { grid-column: center; }
|
|
376
|
+
|
|
377
|
+
/* Backward compatibility: col-narrow maps to content */
|
|
378
|
+
.col-narrow { grid-column: content; }
|
|
379
|
+
|
|
380
|
+
/* ========================================
|
|
381
|
+
Column Utilities - Start/End
|
|
382
|
+
========================================
|
|
383
|
+
|
|
384
|
+
Fine-grained control for custom spans. Combine start and end
|
|
385
|
+
utilities to create any span you need.
|
|
386
|
+
|
|
387
|
+
Example - Span from popout to feature on right:
|
|
388
|
+
<div class="col-start-popout col-end-feature">
|
|
389
|
+
Custom span
|
|
390
|
+
</div>
|
|
391
|
+
*/
|
|
392
|
+
.col-start-full { grid-column-start: full-start; }
|
|
393
|
+
.col-start-feature { grid-column-start: feature-start; }
|
|
394
|
+
.col-start-popout { grid-column-start: popout-start; }
|
|
395
|
+
.col-start-content { grid-column-start: content-start; }
|
|
396
|
+
.col-start-center { grid-column-start: center-start; }
|
|
397
|
+
|
|
398
|
+
/* Backward compatibility */
|
|
399
|
+
.col-start-narrow { grid-column-start: content-start; }
|
|
400
|
+
|
|
401
|
+
.col-end-full { grid-column-end: full-end; }
|
|
402
|
+
.col-end-feature { grid-column-end: feature-end; }
|
|
403
|
+
.col-end-popout { grid-column-end: popout-end; }
|
|
404
|
+
.col-end-content { grid-column-end: content-end; }
|
|
405
|
+
.col-end-center { grid-column-end: center-end; }
|
|
406
|
+
|
|
407
|
+
/* Backward compatibility */
|
|
408
|
+
.col-end-narrow { grid-column-end: content-end; }
|
|
409
|
+
|
|
410
|
+
/* ========================================
|
|
411
|
+
Column Utilities - Left/Right Spans
|
|
412
|
+
========================================
|
|
413
|
+
|
|
414
|
+
Asymmetric spans that anchor to one edge. Perfect for:
|
|
415
|
+
- Split layouts (image left, text right)
|
|
416
|
+
- Overlapping elements
|
|
417
|
+
- Pull quotes that bleed to one edge
|
|
418
|
+
|
|
419
|
+
Pattern: col-{track}-left = full-start → {track}-end
|
|
420
|
+
col-{track}-right = {track}-start → full-end
|
|
421
|
+
|
|
422
|
+
Example - Image bleeds left, caption stays in content:
|
|
423
|
+
<figure class="col-content-left">
|
|
424
|
+
<img class="w-full">Spans from left edge to content</img>
|
|
425
|
+
</figure>
|
|
426
|
+
|
|
427
|
+
Example - Quote pulls right:
|
|
428
|
+
<blockquote class="col-popout-right">
|
|
429
|
+
Spans from popout through to right edge
|
|
430
|
+
</blockquote>
|
|
431
|
+
*/
|
|
432
|
+
.col-feature-left { grid-column: full-start / feature-end; }
|
|
433
|
+
.col-feature-right { grid-column: feature-start / full-end; }
|
|
434
|
+
.col-popout-left { grid-column: full-start / popout-end; }
|
|
435
|
+
.col-popout-right { grid-column: popout-start / full-end; }
|
|
436
|
+
.col-content-left { grid-column: full-start / content-end; }
|
|
437
|
+
.col-content-right { grid-column: content-start / full-end; }
|
|
438
|
+
.col-center-left { grid-column: full-start / center-end; }
|
|
439
|
+
.col-center-right { grid-column: center-start / full-end; }
|
|
440
|
+
|
|
441
|
+
/* Backward compatibility */
|
|
442
|
+
.col-narrow-left { grid-column: full-start / content-end; }
|
|
443
|
+
.col-narrow-right { grid-column: content-start / full-end; }
|
|
444
|
+
|
|
445
|
+
/* ========================================
|
|
446
|
+
Column Utilities - Advanced Spans
|
|
447
|
+
========================================
|
|
448
|
+
|
|
449
|
+
Partial spans between non-adjacent tracks. Use when you need
|
|
450
|
+
elements that span from an inner track outward but not all
|
|
451
|
+
the way to the edge.
|
|
452
|
+
|
|
453
|
+
Example - Card that spans feature to content (not to edge):
|
|
454
|
+
<div class="col-feature-to-content">
|
|
455
|
+
Wide but doesn't bleed to viewport edge
|
|
456
|
+
</div>
|
|
457
|
+
*/
|
|
458
|
+
/* Feature to other columns */
|
|
459
|
+
.col-feature-to-popout { grid-column: feature-start / popout-end; }
|
|
460
|
+
.col-feature-to-content { grid-column: feature-start / content-end; }
|
|
461
|
+
.col-feature-to-center { grid-column: feature-start / center-end; }
|
|
462
|
+
|
|
463
|
+
/* Popout to other columns */
|
|
464
|
+
.col-popout-to-content { grid-column: popout-start / content-end; }
|
|
465
|
+
.col-popout-to-center { grid-column: popout-start / center-end; }
|
|
466
|
+
.col-popout-to-feature { grid-column: popout-start / feature-end; }
|
|
467
|
+
|
|
468
|
+
/* Content to other columns */
|
|
469
|
+
.col-content-to-center { grid-column: content-start / center-end; }
|
|
470
|
+
.col-content-to-popout { grid-column: content-start / popout-end; }
|
|
471
|
+
.col-content-to-feature { grid-column: content-start / feature-end; }
|
|
472
|
+
|
|
473
|
+
/* ----------------------------------------
|
|
474
|
+
Full Limit - Capped Full Width
|
|
475
|
+
----------------------------------------
|
|
476
|
+
|
|
477
|
+
Goes edge-to-edge like col-full, but caps at --full-limit on
|
|
478
|
+
ultra-wide screens. Prevents content from becoming too wide
|
|
479
|
+
on large monitors while still being full-width on normal screens.
|
|
480
|
+
|
|
481
|
+
Example - Hero that doesn't get absurdly wide:
|
|
482
|
+
<section class="col-full-limit">
|
|
483
|
+
Full width up to 115rem, then centered
|
|
484
|
+
</section>
|
|
485
|
+
*/
|
|
486
|
+
.col-full-limit {
|
|
487
|
+
grid-column: full;
|
|
488
|
+
width: 100%;
|
|
489
|
+
max-width: var(--full-limit);
|
|
490
|
+
margin-left: auto;
|
|
491
|
+
margin-right: auto;
|
|
492
|
+
box-sizing: border-box;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/* ========================================
|
|
496
|
+
Padding Utilities
|
|
497
|
+
========================================
|
|
498
|
+
|
|
499
|
+
Match padding to grid measurements for alignment. These utilities
|
|
500
|
+
help content inside non-grid elements align with the grid.
|
|
501
|
+
|
|
502
|
+
--breakout-padding: Fluid padding that matches popout track behavior
|
|
503
|
+
--gap: Matches the outer grid gap
|
|
504
|
+
--computed-gap: Larger gap for full-width elements
|
|
505
|
+
--popout-to-content: Align edges with content track from popout
|
|
506
|
+
--feature-to-content: Align edges with content track from feature
|
|
507
|
+
|
|
508
|
+
Example - Full-width section with content-aligned padding:
|
|
509
|
+
<section class="col-full bg-gray-100 px-feature-to-content">
|
|
510
|
+
<p>This text aligns with content column above/below</p>
|
|
511
|
+
</section>
|
|
512
|
+
|
|
513
|
+
Example - Card with consistent internal spacing:
|
|
514
|
+
<div class="col-popout p-breakout">
|
|
515
|
+
Padding scales with the grid
|
|
516
|
+
</div>
|
|
517
|
+
*/
|
|
518
|
+
.p-breakout { padding: var(--breakout-padding); }
|
|
519
|
+
.px-breakout { padding-left: var(--breakout-padding); padding-right: var(--breakout-padding); }
|
|
520
|
+
.py-breakout { padding-top: var(--breakout-padding); padding-bottom: var(--breakout-padding); }
|
|
521
|
+
.pl-breakout { padding-left: var(--breakout-padding); }
|
|
522
|
+
.pr-breakout { padding-right: var(--breakout-padding); }
|
|
523
|
+
.pt-breakout { padding-top: var(--breakout-padding); }
|
|
524
|
+
.pb-breakout { padding-bottom: var(--breakout-padding); }
|
|
525
|
+
|
|
526
|
+
/* Gap-based padding */
|
|
527
|
+
.p-gap { padding: var(--gap); }
|
|
528
|
+
.px-gap { padding-left: var(--gap); padding-right: var(--gap); }
|
|
529
|
+
.py-gap { padding-top: var(--gap); padding-bottom: var(--gap); }
|
|
530
|
+
.pl-gap { padding-left: var(--gap); }
|
|
531
|
+
.pr-gap { padding-right: var(--gap); }
|
|
532
|
+
.pt-gap { padding-top: var(--gap); }
|
|
533
|
+
.pb-gap { padding-bottom: var(--gap); }
|
|
534
|
+
|
|
535
|
+
/* Full-gap padding (computed, for full-width elements) */
|
|
536
|
+
.p-full-gap { padding: var(--computed-gap); }
|
|
537
|
+
.px-full-gap { padding-left: var(--computed-gap); padding-right: var(--computed-gap); }
|
|
538
|
+
.py-full-gap { padding-top: var(--computed-gap); padding-bottom: var(--computed-gap); }
|
|
539
|
+
.pl-full-gap { padding-left: var(--computed-gap); }
|
|
540
|
+
.pr-full-gap { padding-right: var(--computed-gap); }
|
|
541
|
+
.pt-full-gap { padding-top: var(--computed-gap); }
|
|
542
|
+
.pb-full-gap { padding-bottom: var(--computed-gap); }
|
|
543
|
+
|
|
544
|
+
/* Popout-width padding */
|
|
545
|
+
.p-popout { padding: var(--popout); }
|
|
546
|
+
.px-popout { padding-left: var(--popout); padding-right: var(--popout); }
|
|
547
|
+
.py-popout { padding-top: var(--popout); padding-bottom: var(--popout); }
|
|
548
|
+
.pl-popout { padding-left: var(--popout); }
|
|
549
|
+
.pr-popout { padding-right: var(--popout); }
|
|
550
|
+
.pt-popout { padding-top: var(--popout); }
|
|
551
|
+
.pb-popout { padding-bottom: var(--popout); }
|
|
552
|
+
|
|
553
|
+
/* Alignment padding - align content inside wider columns */
|
|
554
|
+
.p-popout-to-content { padding: var(--popout-to-content); }
|
|
555
|
+
.px-popout-to-content { padding-left: var(--popout-to-content); padding-right: var(--popout-to-content); }
|
|
556
|
+
.py-popout-to-content { padding-top: var(--popout-to-content); padding-bottom: var(--popout-to-content); }
|
|
557
|
+
.pt-popout-to-content { padding-top: var(--popout-to-content); }
|
|
558
|
+
.pr-popout-to-content { padding-right: var(--popout-to-content); }
|
|
559
|
+
.pb-popout-to-content { padding-bottom: var(--popout-to-content); }
|
|
560
|
+
.pl-popout-to-content { padding-left: var(--popout-to-content); }
|
|
561
|
+
|
|
562
|
+
.p-feature-to-content { padding: var(--feature-to-content); }
|
|
563
|
+
.px-feature-to-content { padding-left: var(--feature-to-content); padding-right: var(--feature-to-content); }
|
|
564
|
+
.py-feature-to-content { padding-top: var(--feature-to-content); padding-bottom: var(--feature-to-content); }
|
|
565
|
+
.pt-feature-to-content { padding-top: var(--feature-to-content); }
|
|
566
|
+
.pr-feature-to-content { padding-right: var(--feature-to-content); }
|
|
567
|
+
.pb-feature-to-content { padding-bottom: var(--feature-to-content); }
|
|
568
|
+
.pl-feature-to-content { padding-left: var(--feature-to-content); }
|
|
569
|
+
|
|
570
|
+
/* ========================================
|
|
571
|
+
Margin Utilities
|
|
572
|
+
========================================
|
|
573
|
+
|
|
574
|
+
Same values as padding utilities, but for margins. Includes
|
|
575
|
+
negative variants for pulling elements outside their container.
|
|
576
|
+
|
|
577
|
+
Example - Pull image outside its container:
|
|
578
|
+
<div class="col-content">
|
|
579
|
+
<img class="-mx-breakout">Bleeds into popout area</img>
|
|
580
|
+
</div>
|
|
581
|
+
|
|
582
|
+
Example - Overlap previous section:
|
|
583
|
+
<section class="-mt-gap">
|
|
584
|
+
Pulls up into the section above
|
|
585
|
+
</section>
|
|
586
|
+
*/
|
|
587
|
+
.m-breakout { margin: var(--breakout-padding); }
|
|
588
|
+
.mx-breakout { margin-left: var(--breakout-padding); margin-right: var(--breakout-padding); }
|
|
589
|
+
.my-breakout { margin-top: var(--breakout-padding); margin-bottom: var(--breakout-padding); }
|
|
590
|
+
.ml-breakout { margin-left: var(--breakout-padding); }
|
|
591
|
+
.mr-breakout { margin-right: var(--breakout-padding); }
|
|
592
|
+
.mt-breakout { margin-top: var(--breakout-padding); }
|
|
593
|
+
.mb-breakout { margin-bottom: var(--breakout-padding); }
|
|
594
|
+
|
|
595
|
+
/* Negative margins */
|
|
596
|
+
.-m-breakout { margin: calc(var(--breakout-padding) * -1); }
|
|
597
|
+
.-mx-breakout { margin-left: calc(var(--breakout-padding) * -1); margin-right: calc(var(--breakout-padding) * -1); }
|
|
598
|
+
.-my-breakout { margin-top: calc(var(--breakout-padding) * -1); margin-bottom: calc(var(--breakout-padding) * -1); }
|
|
599
|
+
.-ml-breakout { margin-left: calc(var(--breakout-padding) * -1); }
|
|
600
|
+
.-mr-breakout { margin-right: calc(var(--breakout-padding) * -1); }
|
|
601
|
+
.-mt-breakout { margin-top: calc(var(--breakout-padding) * -1); }
|
|
602
|
+
.-mb-breakout { margin-bottom: calc(var(--breakout-padding) * -1); }
|
|
603
|
+
|
|
604
|
+
/* Gap-based margins */
|
|
605
|
+
.m-gap { margin: var(--gap); }
|
|
606
|
+
.mx-gap { margin-left: var(--gap); margin-right: var(--gap); }
|
|
607
|
+
.my-gap { margin-top: var(--gap); margin-bottom: var(--gap); }
|
|
608
|
+
.ml-gap { margin-left: var(--gap); }
|
|
609
|
+
.mr-gap { margin-right: var(--gap); }
|
|
610
|
+
.mt-gap { margin-top: var(--gap); }
|
|
611
|
+
.mb-gap { margin-bottom: var(--gap); }
|
|
612
|
+
|
|
613
|
+
/* Negative margins */
|
|
614
|
+
.-m-gap { margin: calc(var(--gap) * -1); }
|
|
615
|
+
.-mx-gap { margin-left: calc(var(--gap) * -1); margin-right: calc(var(--gap) * -1); }
|
|
616
|
+
.-my-gap { margin-top: calc(var(--gap) * -1); margin-bottom: calc(var(--gap) * -1); }
|
|
617
|
+
.-ml-gap { margin-left: calc(var(--gap) * -1); }
|
|
618
|
+
.-mr-gap { margin-right: calc(var(--gap) * -1); }
|
|
619
|
+
.-mt-gap { margin-top: calc(var(--gap) * -1); }
|
|
620
|
+
.-mb-gap { margin-bottom: calc(var(--gap) * -1); }
|
|
621
|
+
|
|
622
|
+
/* Full-gap margins */
|
|
623
|
+
.m-full-gap { margin: var(--computed-gap); }
|
|
624
|
+
.mx-full-gap { margin-left: var(--computed-gap); margin-right: var(--computed-gap); }
|
|
625
|
+
.my-full-gap { margin-top: var(--computed-gap); margin-bottom: var(--computed-gap); }
|
|
626
|
+
.ml-full-gap { margin-left: var(--computed-gap); }
|
|
627
|
+
.mr-full-gap { margin-right: var(--computed-gap); }
|
|
628
|
+
.mt-full-gap { margin-top: var(--computed-gap); }
|
|
629
|
+
.mb-full-gap { margin-bottom: var(--computed-gap); }
|
|
630
|
+
|
|
631
|
+
/* Negative margins */
|
|
632
|
+
.-m-full-gap { margin: calc(var(--computed-gap) * -1); }
|
|
633
|
+
.-mx-full-gap { margin-left: calc(var(--computed-gap) * -1); margin-right: calc(var(--computed-gap) * -1); }
|
|
634
|
+
.-my-full-gap { margin-top: calc(var(--computed-gap) * -1); margin-bottom: calc(var(--computed-gap) * -1); }
|
|
635
|
+
.-ml-full-gap { margin-left: calc(var(--computed-gap) * -1); }
|
|
636
|
+
.-mr-full-gap { margin-right: calc(var(--computed-gap) * -1); }
|
|
637
|
+
.-mt-full-gap { margin-top: calc(var(--computed-gap) * -1); }
|
|
638
|
+
.-mb-full-gap { margin-bottom: calc(var(--computed-gap) * -1); }
|
|
639
|
+
|
|
640
|
+
/* Popout-width margins */
|
|
641
|
+
.m-popout { margin: var(--popout); }
|
|
642
|
+
.mx-popout { margin-left: var(--popout); margin-right: var(--popout); }
|
|
643
|
+
.my-popout { margin-top: var(--popout); margin-bottom: var(--popout); }
|
|
644
|
+
.ml-popout { margin-left: var(--popout); }
|
|
645
|
+
.mr-popout { margin-right: var(--popout); }
|
|
646
|
+
.mt-popout { margin-top: var(--popout); }
|
|
647
|
+
.mb-popout { margin-bottom: var(--popout); }
|
|
648
|
+
|
|
649
|
+
/* Negative margins */
|
|
650
|
+
.-m-popout { margin: calc(var(--popout) * -1); }
|
|
651
|
+
.-mx-popout { margin-left: calc(var(--popout) * -1); margin-right: calc(var(--popout) * -1); }
|
|
652
|
+
.-my-popout { margin-top: calc(var(--popout) * -1); margin-bottom: calc(var(--popout) * -1); }
|
|
653
|
+
.-ml-popout { margin-left: calc(var(--popout) * -1); }
|
|
654
|
+
.-mr-popout { margin-right: calc(var(--popout) * -1); }
|
|
655
|
+
.-mt-popout { margin-top: calc(var(--popout) * -1); }
|
|
656
|
+
.-mb-popout { margin-bottom: calc(var(--popout) * -1); }
|