@fpkit/acss 3.6.0 → 3.7.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/libs/{chunk-URBGDUFN.cjs → chunk-75YQDONV.cjs} +3 -3
- package/libs/chunk-AOFQDQVS.cjs +17 -0
- package/libs/chunk-AOFQDQVS.cjs.map +1 -0
- package/libs/{chunk-ZF6Y7W57.js → chunk-G3TFKMWB.js} +2 -2
- package/libs/chunk-Q7OAQLUT.js +10 -0
- package/libs/chunk-Q7OAQLUT.js.map +1 -0
- package/libs/components/dialog/dialog.cjs +4 -4
- package/libs/components/dialog/dialog.js +2 -2
- package/libs/components/heading/heading.cjs +2 -2
- package/libs/components/heading/heading.d.cts +1 -1
- package/libs/components/heading/heading.d.ts +1 -1
- package/libs/components/heading/heading.js +1 -1
- package/libs/components/title/title.css +1 -0
- package/libs/components/title/title.css.map +1 -0
- package/libs/components/title/title.min.css +3 -0
- package/libs/{heading-7446cb46.d.ts → heading-81eef89a.d.ts} +42 -0
- package/libs/index.cjs +5 -5
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +1 -1
- package/libs/index.d.ts +1 -1
- package/libs/index.js +2 -2
- package/package.json +2 -2
- package/src/components/box/box.stories.tsx +1 -1
- package/src/components/cluster/cluster.stories.tsx +1 -1
- package/src/components/col/README.mdx +233 -9
- package/src/components/col/STYLES.mdx +1380 -0
- package/src/components/col/col.stories.tsx +1 -1
- package/src/components/grid/grid.stories.tsx +130 -35
- package/src/components/row/row.stories.tsx +1 -1
- package/src/components/stack/stack.stories.tsx +219 -60
- package/src/components/title/README.mdx +87 -1
- package/src/components/title/STYLES.mdx +501 -0
- package/src/components/title/title.scss +51 -0
- package/src/components/title/title.stories.tsx +158 -0
- package/src/components/title/title.test.tsx +113 -0
- package/src/components/title/title.tsx +53 -1
- package/src/index.scss +1 -0
- package/src/sass/columns.stories.tsx +434 -10
- package/src/styles/index.css +74 -0
- package/src/styles/index.css.map +1 -1
- package/src/styles/title/title.css +75 -0
- package/src/styles/title/title.css.map +1 -0
- package/libs/chunk-2C3YLBWP.cjs +0 -17
- package/libs/chunk-2C3YLBWP.cjs.map +0 -1
- package/libs/chunk-KDMX3FAW.js +0 -10
- package/libs/chunk-KDMX3FAW.js.map +0 -1
- /package/libs/{chunk-URBGDUFN.cjs.map → chunk-75YQDONV.cjs.map} +0 -0
- /package/libs/{chunk-ZF6Y7W57.js.map → chunk-G3TFKMWB.js.map} +0 -0
|
@@ -0,0 +1,1380 @@
|
|
|
1
|
+
import { Meta } from "@storybook/addon-docs/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Layout/Col/Styles" />
|
|
4
|
+
|
|
5
|
+
# Column System Styles
|
|
6
|
+
|
|
7
|
+
Comprehensive CSS utility system for building responsive 12-column layouts with mobile-first breakpoints.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
The fpkit column styling system provides a complete set of column utilities supporting responsive layouts, offsets, visual reordering, and flexible sizing. All styles use CSS custom properties for easy customization and theming, with rem-based sizing for accessibility.
|
|
12
|
+
|
|
13
|
+
### Key Features
|
|
14
|
+
|
|
15
|
+
- **12-column grid** - `.col-1` (8.333%) through `.col-12` (100%) classes
|
|
16
|
+
- **Mobile-first responsive** - 3 breakpoints (sm, md, lg) with 183 generated utilities
|
|
17
|
+
- **Flexbox-based** - Works with `.col-row`, Row component, or custom flex containers
|
|
18
|
+
- **No base class** - Pure utility composition following Grid.Item pattern
|
|
19
|
+
- **CSS custom properties** - Breakpoint and width variables for customization
|
|
20
|
+
- **Rem-based sizing** - All measurements use rem units (1rem = 16px)
|
|
21
|
+
- **Accessibility** - Proper focus handling and visual order warnings
|
|
22
|
+
|
|
23
|
+
## CSS Custom Properties
|
|
24
|
+
|
|
25
|
+
### Breakpoint Variables
|
|
26
|
+
|
|
27
|
+
The column system exposes breakpoint values as CSS custom properties for JavaScript access and documentation. Media queries use literal SCSS values (not CSS variables).
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
:root {
|
|
31
|
+
/* Breakpoint values (for JS access) */
|
|
32
|
+
--col-breakpoint-xs: 0rem; /* 0px - base mobile */
|
|
33
|
+
--col-breakpoint-sm: 30rem; /* 480px - large phones */
|
|
34
|
+
--col-breakpoint-md: 48rem; /* 768px - tablets */
|
|
35
|
+
--col-breakpoint-lg: 64rem; /* 1024px - desktops */
|
|
36
|
+
|
|
37
|
+
/* Legacy support */
|
|
38
|
+
--col-breakpoint: var(--col-breakpoint-md);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| Variable | Value | Pixel Equivalent | Description | Utility Prefix |
|
|
43
|
+
|----------|-------|------------------|-------------|----------------|
|
|
44
|
+
| `--col-breakpoint-xs` | `0rem` | 0px | Mobile portrait (base) | (none - base classes) |
|
|
45
|
+
| `--col-breakpoint-sm` | `30rem` | 480px | Mobile landscape, large phones | `.col-sm-*` |
|
|
46
|
+
| `--col-breakpoint-md` | `48rem` | 768px | Tablets, small laptops | `.col-md-*` |
|
|
47
|
+
| `--col-breakpoint-lg` | `64rem` | 1024px | Desktops, large screens | `.col-lg-*` |
|
|
48
|
+
|
|
49
|
+
### Column Width Variables
|
|
50
|
+
|
|
51
|
+
Column widths are defined as percentage-based CSS custom properties:
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
:root {
|
|
55
|
+
/* Column width percentages (fractions of 12) */
|
|
56
|
+
--col-1: 8.333333%; /* 1/12 */
|
|
57
|
+
--col-2: 16.666667%; /* 2/12 */
|
|
58
|
+
--col-3: 25%; /* 3/12 */
|
|
59
|
+
--col-4: 33.333333%; /* 4/12 */
|
|
60
|
+
--col-5: 41.666667%; /* 5/12 */
|
|
61
|
+
--col-6: 50%; /* 6/12 */
|
|
62
|
+
--col-7: 58.333333%; /* 7/12 */
|
|
63
|
+
--col-8: 66.666667%; /* 8/12 */
|
|
64
|
+
--col-9: 75%; /* 9/12 */
|
|
65
|
+
--col-10: 83.333333%; /* 10/12 */
|
|
66
|
+
--col-11: 91.666667%; /* 11/12 */
|
|
67
|
+
--col-12: 100%; /* 12/12 */
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Customizing Breakpoints
|
|
72
|
+
|
|
73
|
+
You can override breakpoint values globally (affects JavaScript access only, not media queries):
|
|
74
|
+
|
|
75
|
+
```css
|
|
76
|
+
/* Custom breakpoints (CSS variable override) */
|
|
77
|
+
:root {
|
|
78
|
+
--col-breakpoint-md: 50rem; /* Changes reference value to 800px */
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Note:** Media queries use literal SCSS values and cannot be changed via CSS custom properties. To change actual breakpoint behavior, modify `$col-breakpoints` in `_columns.scss`.
|
|
83
|
+
|
|
84
|
+
## Mobile-First Responsive System
|
|
85
|
+
|
|
86
|
+
### How Mobile-First Works
|
|
87
|
+
|
|
88
|
+
**Key Principle:** Styles cascade upward from smallest to largest breakpoint.
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Mobile (< 480px) → Tablet (≥ 768px) → Desktop (≥ 1024px)
|
|
92
|
+
Base .col-md-* .col-lg-*
|
|
93
|
+
(no prefix) (overrides base) (overrides md & base)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Example Cascade:**
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<div class="col-12 col-md-6 col-lg-4">
|
|
100
|
+
<!-- Mobile (< 768px): .col-12 applies → 100% width -->
|
|
101
|
+
<!-- Tablet (≥ 768px): .col-md-6 overrides → 50% width -->
|
|
102
|
+
<!-- Desktop (≥ 1024px): .col-lg-4 overrides → 33.33% width -->
|
|
103
|
+
</div>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**How it works:**
|
|
107
|
+
|
|
108
|
+
1. **Mobile** (< 768px): Only `.col-12` applies (100% width, column stacks)
|
|
109
|
+
2. **Tablet** (≥ 768px): `.col-md-6` activates and overrides `.col-12` (50% width, 2 columns per row)
|
|
110
|
+
3. **Desktop** (≥ 1024px): `.col-lg-4` activates and overrides both previous classes (33.33% width, 3 columns per row)
|
|
111
|
+
|
|
112
|
+
### Breakpoint Reference
|
|
113
|
+
|
|
114
|
+
| Breakpoint | Prefix | Min Width (rem) | Min Width (px) | Target Devices | When to Use |
|
|
115
|
+
|------------|--------|-----------------|----------------|----------------|-------------|
|
|
116
|
+
| **xs** | (none) | `0rem` | 0px | Mobile portrait | Default, always applies |
|
|
117
|
+
| **sm** | `.col-sm-*` | `30rem` | 480px | Mobile landscape, large phones | iPhone Plus, Android phones |
|
|
118
|
+
| **md** | `.col-md-*` | `48rem` | 768px | Tablets | iPad, Android tablets |
|
|
119
|
+
| **lg** | `.col-lg-*` | `64rem` | 1024px | Desktops | Laptops, desktop monitors |
|
|
120
|
+
|
|
121
|
+
**Progressive Enhancement Example:**
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<!-- 1 column mobile → 2 columns tablet → 4 columns desktop -->
|
|
125
|
+
<div class="col-row">
|
|
126
|
+
<div class="col-12 col-md-6 col-lg-3">Column 1</div>
|
|
127
|
+
<div class="col-12 col-md-6 col-lg-3">Column 2</div>
|
|
128
|
+
<div class="col-12 col-md-6 col-lg-3">Column 3</div>
|
|
129
|
+
<div class="col-12 col-md-6 col-lg-3">Column 4</div>
|
|
130
|
+
</div>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Container Requirements
|
|
134
|
+
|
|
135
|
+
### .col-row Utility
|
|
136
|
+
|
|
137
|
+
Columns require a flex container with `flex-wrap: wrap`. The `.col-row` utility provides a convenient container:
|
|
138
|
+
|
|
139
|
+
```css
|
|
140
|
+
.col-row {
|
|
141
|
+
display: flex;
|
|
142
|
+
flex-wrap: wrap;
|
|
143
|
+
gap: var(--spacing-md); /* Default 1rem gap */
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Usage:**
|
|
148
|
+
|
|
149
|
+
```html
|
|
150
|
+
<div class="col-row">
|
|
151
|
+
<div class="col-6">Column 1</div>
|
|
152
|
+
<div class="col-6">Column 2</div>
|
|
153
|
+
</div>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Alternative Containers
|
|
157
|
+
|
|
158
|
+
**Option 1: Row React Component (recommended for React apps)**
|
|
159
|
+
|
|
160
|
+
```jsx
|
|
161
|
+
<Row gap="md">
|
|
162
|
+
<div className="col-6">Column 1</div>
|
|
163
|
+
<div className="col-6">Column 2</div>
|
|
164
|
+
</Row>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Option 2: Flex Component**
|
|
168
|
+
|
|
169
|
+
```jsx
|
|
170
|
+
<Flex wrap="wrap" gap="md">
|
|
171
|
+
<div className="col-6">Column 1</div>
|
|
172
|
+
<div className="col-6">Column 2</div>
|
|
173
|
+
</Flex>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Option 3: Custom Flex Container**
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<div style="display: flex; flex-wrap: wrap; gap: 1rem;">
|
|
180
|
+
<div class="col-6">Column 1</div>
|
|
181
|
+
<div class="col-6">Column 2</div>
|
|
182
|
+
</div>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Base Column Classes
|
|
186
|
+
|
|
187
|
+
### Column Span Utilities
|
|
188
|
+
|
|
189
|
+
Base column classes provide fractional widths on desktop (≥ 768px) and stack to 100% width on mobile (< 768px).
|
|
190
|
+
|
|
191
|
+
| Class | Width (Desktop ≥ 768px) | Width (Mobile < 768px) | CSS |
|
|
192
|
+
|-------|-------------------------|------------------------|-----|
|
|
193
|
+
| `.col-1` | 8.333% (1/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-1);` desktop |
|
|
194
|
+
| `.col-2` | 16.667% (2/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-2);` desktop |
|
|
195
|
+
| `.col-3` | 25% (3/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-3);` desktop |
|
|
196
|
+
| `.col-4` | 33.333% (4/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-4);` desktop |
|
|
197
|
+
| `.col-5` | 41.667% (5/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-5);` desktop |
|
|
198
|
+
| `.col-6` | 50% (6/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-6);` desktop |
|
|
199
|
+
| `.col-7` | 58.333% (7/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-7);` desktop |
|
|
200
|
+
| `.col-8` | 66.667% (8/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-8);` desktop |
|
|
201
|
+
| `.col-9` | 75% (9/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-9);` desktop |
|
|
202
|
+
| `.col-10` | 83.333% (10/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-10);` desktop |
|
|
203
|
+
| `.col-11` | 91.667% (11/12) | 100% (stacked) | `flex: 0 0 100%;` mobile, `flex: 0 0 var(--col-11);` desktop |
|
|
204
|
+
| `.col-12` | 100% (full width) | 100% (full width) | `flex: 0 0 100%;` all sizes |
|
|
205
|
+
|
|
206
|
+
**Example:**
|
|
207
|
+
|
|
208
|
+
```html
|
|
209
|
+
<div class="col-row">
|
|
210
|
+
<div class="col-6">50% on desktop, 100% on mobile</div>
|
|
211
|
+
<div class="col-6">50% on desktop, 100% on mobile</div>
|
|
212
|
+
</div>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**CSS Implementation:**
|
|
216
|
+
|
|
217
|
+
```css
|
|
218
|
+
/* Mobile-first (all sizes) */
|
|
219
|
+
.col-1, .col-2, .col-3, .col-4, .col-5, .col-6,
|
|
220
|
+
.col-7, .col-8, .col-9, .col-10, .col-11, .col-12 {
|
|
221
|
+
flex: 0 0 100%; /* Stack on mobile */
|
|
222
|
+
min-width: 0;
|
|
223
|
+
box-sizing: border-box;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* Desktop (≥ 768px) */
|
|
227
|
+
@media (width >= 48rem) {
|
|
228
|
+
.col-1 { flex: 0 0 var(--col-1); max-width: var(--col-1); }
|
|
229
|
+
.col-2 { flex: 0 0 var(--col-2); max-width: var(--col-2); }
|
|
230
|
+
.col-3 { flex: 0 0 var(--col-3); max-width: var(--col-3); }
|
|
231
|
+
/* ... through col-12 */
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Auto-Width Columns
|
|
236
|
+
|
|
237
|
+
`.col-auto` - Width based on content, not grid fractions:
|
|
238
|
+
|
|
239
|
+
```html
|
|
240
|
+
<div class="col-row">
|
|
241
|
+
<div class="col-auto">Button</div>
|
|
242
|
+
<div class="col-auto">Another Button</div>
|
|
243
|
+
</div>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**CSS:**
|
|
247
|
+
|
|
248
|
+
```css
|
|
249
|
+
.col-auto {
|
|
250
|
+
flex: 0 0 auto;
|
|
251
|
+
width: auto;
|
|
252
|
+
min-width: 0;
|
|
253
|
+
box-sizing: border-box;
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Use Cases:**
|
|
258
|
+
- Buttons and button groups
|
|
259
|
+
- Badges and tags
|
|
260
|
+
- Icon containers
|
|
261
|
+
- Navigation items
|
|
262
|
+
|
|
263
|
+
### Flex-Grow Columns
|
|
264
|
+
|
|
265
|
+
`.col-flex` - Grows to fill remaining space after fixed columns:
|
|
266
|
+
|
|
267
|
+
```html
|
|
268
|
+
<div class="col-row">
|
|
269
|
+
<div class="col-3">Fixed sidebar (25%)</div>
|
|
270
|
+
<div class="col-flex">Main content (fills remaining 75%)</div>
|
|
271
|
+
</div>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**CSS:**
|
|
275
|
+
|
|
276
|
+
```css
|
|
277
|
+
/* Mobile (< 768px) - stacks like other columns */
|
|
278
|
+
.col-flex {
|
|
279
|
+
flex: 0 0 100%;
|
|
280
|
+
min-width: 0;
|
|
281
|
+
box-sizing: border-box;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* Desktop (≥ 768px) - grows to fill space */
|
|
285
|
+
@media (width >= 48rem) {
|
|
286
|
+
.col-flex {
|
|
287
|
+
flex: 1 1 0%;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**How flex-basis: 0% works:**
|
|
293
|
+
|
|
294
|
+
When multiple `.col-flex` columns exist, `flex-basis: 0%` ensures they share remaining space equally:
|
|
295
|
+
|
|
296
|
+
```html
|
|
297
|
+
<div class="col-row">
|
|
298
|
+
<div class="col-2">Fixed (16.67%)</div>
|
|
299
|
+
<div class="col-flex">Section 1 (41.67% - half of remaining)</div>
|
|
300
|
+
<div class="col-flex">Section 2 (41.67% - half of remaining)</div>
|
|
301
|
+
</div>
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Comparison: .col-auto vs .col-flex
|
|
305
|
+
|
|
306
|
+
| Feature | `.col-auto` | `.col-flex` |
|
|
307
|
+
|---------|-------------|-------------|
|
|
308
|
+
| **CSS** | `flex: 0 0 auto` | `flex: 1 1 0%` (desktop), `flex: 0 0 100%` (mobile) |
|
|
309
|
+
| **Sizing** | Content-based width | Grows to fill available space |
|
|
310
|
+
| **Use case** | Buttons, labels, icons | Main content areas, flexible sections |
|
|
311
|
+
| **Mobile** | Content-based | 100% width (stacks) |
|
|
312
|
+
| **Desktop** | Content-based | Fills remaining space |
|
|
313
|
+
| **Multiple columns** | Each sizes to its content | Share remaining space equally |
|
|
314
|
+
| **Example** | Button group | Sidebar + main content layout |
|
|
315
|
+
|
|
316
|
+
## Responsive Column Utilities
|
|
317
|
+
|
|
318
|
+
### Responsive Span Classes
|
|
319
|
+
|
|
320
|
+
Apply different column widths at different breakpoints using responsive span utilities.
|
|
321
|
+
|
|
322
|
+
**Available Classes:**
|
|
323
|
+
|
|
324
|
+
| Breakpoint | Classes | Example | Applies At |
|
|
325
|
+
|------------|---------|---------|------------|
|
|
326
|
+
| Small (480px+) | `.col-sm-{1-12}` | `.col-sm-6` | ≥ 30rem (480px) |
|
|
327
|
+
| Medium (768px+) | `.col-md-{1-12}` | `.col-md-4` | ≥ 48rem (768px) |
|
|
328
|
+
| Large (1024px+) | `.col-lg-{1-12}` | `.col-lg-3` | ≥ 64rem (1024px) |
|
|
329
|
+
|
|
330
|
+
**Progressive Enhancement Pattern:**
|
|
331
|
+
|
|
332
|
+
```html
|
|
333
|
+
<div class="col-row">
|
|
334
|
+
<!-- 1 column mobile, 2 columns tablet, 3 columns desktop -->
|
|
335
|
+
<div class="col-12 col-md-6 col-lg-4">Column 1</div>
|
|
336
|
+
<div class="col-12 col-md-6 col-lg-4">Column 2</div>
|
|
337
|
+
<div class="col-12 col-md-6 col-lg-4">Column 3</div>
|
|
338
|
+
</div>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**How it works:**
|
|
342
|
+
|
|
343
|
+
- **Mobile** (< 768px): `.col-12` applies → 100% width (1 column)
|
|
344
|
+
- **Tablet** (≥ 768px): `.col-md-6` overrides → 50% width (2 columns)
|
|
345
|
+
- **Desktop** (≥ 1024px): `.col-lg-4` overrides → 33.33% width (3 columns)
|
|
346
|
+
|
|
347
|
+
**All Responsive Span Classes:**
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
.col-sm-1 through .col-sm-12 (applies at ≥ 480px)
|
|
351
|
+
.col-md-1 through .col-md-12 (applies at ≥ 768px)
|
|
352
|
+
.col-lg-1 through .col-lg-12 (applies at ≥ 1024px)
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Responsive Auto-Width
|
|
356
|
+
|
|
357
|
+
Apply content-based width at specific breakpoints:
|
|
358
|
+
|
|
359
|
+
| Class | Applies At | Behavior |
|
|
360
|
+
|-------|-----------|----------|
|
|
361
|
+
| `.col-auto` | All sizes | Content width |
|
|
362
|
+
| `.col-sm-auto` | ≥ 480px | Content width |
|
|
363
|
+
| `.col-md-auto` | ≥ 768px | Content width |
|
|
364
|
+
| `.col-lg-auto` | ≥ 1024px | Content width |
|
|
365
|
+
|
|
366
|
+
**Example:**
|
|
367
|
+
|
|
368
|
+
```html
|
|
369
|
+
<!-- Full-width mobile, auto-width tablet+ -->
|
|
370
|
+
<div class="col-row">
|
|
371
|
+
<div class="col-12 col-md-auto">
|
|
372
|
+
<button>Save</button>
|
|
373
|
+
</div>
|
|
374
|
+
<div class="col-12 col-md-auto">
|
|
375
|
+
<button>Cancel</button>
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Responsive Flex-Grow
|
|
381
|
+
|
|
382
|
+
Apply flex-grow behavior at specific breakpoints:
|
|
383
|
+
|
|
384
|
+
| Class | Applies At | Behavior |
|
|
385
|
+
|-------|-----------|----------|
|
|
386
|
+
| `.col-flex` | All sizes | Fills space (desktop), stacks (mobile) |
|
|
387
|
+
| `.col-sm-flex` | ≥ 480px | Fills space |
|
|
388
|
+
| `.col-md-flex` | ≥ 768px | Fills space |
|
|
389
|
+
| `.col-lg-flex` | ≥ 1024px | Fills space |
|
|
390
|
+
|
|
391
|
+
**Example:**
|
|
392
|
+
|
|
393
|
+
```html
|
|
394
|
+
<!-- Stacked mobile, sidebar layout tablet+ -->
|
|
395
|
+
<div class="col-row">
|
|
396
|
+
<div class="col-12 col-md-3">Sidebar (25% on tablet+)</div>
|
|
397
|
+
<div class="col-12 col-md-flex">Main content (fills 75% on tablet+)</div>
|
|
398
|
+
</div>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Responsive Offset Utilities
|
|
402
|
+
|
|
403
|
+
### Offset Classes
|
|
404
|
+
|
|
405
|
+
Push columns to the right using left margin. Offsets are desktop-only by default (≥ 768px), with responsive variants available.
|
|
406
|
+
|
|
407
|
+
**Base Offsets (Desktop ≥ 768px only):**
|
|
408
|
+
|
|
409
|
+
| Class | Offset | Margin-Left | Use Case |
|
|
410
|
+
|-------|--------|-------------|----------|
|
|
411
|
+
| `.col-offset-0` | 0% | 0 | Reset offset |
|
|
412
|
+
| `.col-offset-1` | 8.333% | 1/12 | 1-column push |
|
|
413
|
+
| `.col-offset-2` | 16.667% | 2/12 | 2-column push |
|
|
414
|
+
| `.col-offset-3` | 25% | 3/12 | 3-column push |
|
|
415
|
+
| `.col-offset-4` | 33.333% | 4/12 | 4-column push |
|
|
416
|
+
| `.col-offset-5` | 41.667% | 5/12 | 5-column push |
|
|
417
|
+
| `.col-offset-6` | 50% | 6/12 | 6-column push |
|
|
418
|
+
| `.col-offset-7` | 58.333% | 7/12 | 7-column push |
|
|
419
|
+
| `.col-offset-8` | 66.667% | 8/12 | 8-column push |
|
|
420
|
+
| `.col-offset-9` | 75% | 9/12 | 9-column push |
|
|
421
|
+
| `.col-offset-10` | 83.333% | 10/12 | 10-column push |
|
|
422
|
+
| `.col-offset-11` | 91.667% | 11/12 | 11-column push |
|
|
423
|
+
|
|
424
|
+
**Responsive Offsets:**
|
|
425
|
+
|
|
426
|
+
```
|
|
427
|
+
.col-sm-offset-{0-11} (applies at ≥ 480px)
|
|
428
|
+
.col-md-offset-{0-11} (applies at ≥ 768px)
|
|
429
|
+
.col-lg-offset-{0-11} (applies at ≥ 1024px)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**CSS Implementation:**
|
|
433
|
+
|
|
434
|
+
```css
|
|
435
|
+
@media (width >= 48rem) {
|
|
436
|
+
.col-offset-3 {
|
|
437
|
+
margin-inline-start: var(--col-3); /* 25% */
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Centering Pattern
|
|
443
|
+
|
|
444
|
+
Center a column by offsetting it:
|
|
445
|
+
|
|
446
|
+
```html
|
|
447
|
+
<!-- Centered column: 50% width, 25% left margin -->
|
|
448
|
+
<div class="col-row">
|
|
449
|
+
<div class="col-6 col-offset-3">
|
|
450
|
+
Centered content
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
**Math:** 6 columns (50%) + 3 column offset (25%) + 3 columns empty (25%) = 12 columns total
|
|
456
|
+
|
|
457
|
+
### Progressive Centering
|
|
458
|
+
|
|
459
|
+
Content gets narrower and more centered on larger screens:
|
|
460
|
+
|
|
461
|
+
```html
|
|
462
|
+
<div class="col-row">
|
|
463
|
+
<div class="col-10 col-offset-1 col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3">
|
|
464
|
+
<article>Progressively centered article content</article>
|
|
465
|
+
</div>
|
|
466
|
+
</div>
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Result:**
|
|
470
|
+
|
|
471
|
+
- **Mobile** (< 480px): 100% width (`.col-10` doesn't apply yet), no offset
|
|
472
|
+
- **Tablet** (≥ 480px): 83.33% width (10/12), 8.33% left margin (1/12)
|
|
473
|
+
- **Desktop** (≥ 768px): 66.67% width (8/12), 16.67% left margin (2/12)
|
|
474
|
+
- **Large Desktop** (≥ 1024px): 50% width (6/12), 25% left margin (3/12)
|
|
475
|
+
|
|
476
|
+
## Responsive Order Utilities
|
|
477
|
+
|
|
478
|
+
### Order Classes
|
|
479
|
+
|
|
480
|
+
Change visual order without changing DOM structure using flexbox `order` property.
|
|
481
|
+
|
|
482
|
+
**Base Order (Desktop ≥ 768px only):**
|
|
483
|
+
|
|
484
|
+
| Class | Order Value | Description |
|
|
485
|
+
|-------|-------------|-------------|
|
|
486
|
+
| `.col-order-first` | `-1` | Display first (before order: 0) |
|
|
487
|
+
| `.col-order-last` | `13` | Display last (after order: 12) |
|
|
488
|
+
| `.col-order-0` | `0` | Default order (source order) |
|
|
489
|
+
| `.col-order-1` | `1` | Order position 1 |
|
|
490
|
+
| `.col-order-2` | `2` | Order position 2 |
|
|
491
|
+
| ... | ... | ... |
|
|
492
|
+
| `.col-order-12` | `12` | Order position 12 |
|
|
493
|
+
|
|
494
|
+
**Responsive Order:**
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
.col-sm-order-{first|last|0-12} (applies at ≥ 480px)
|
|
498
|
+
.col-md-order-{first|last|0-12} (applies at ≥ 768px)
|
|
499
|
+
.col-lg-order-{first|last|0-12} (applies at ≥ 1024px)
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
**Example:**
|
|
503
|
+
|
|
504
|
+
```html
|
|
505
|
+
<div class="col-row">
|
|
506
|
+
<!-- DOM order: A, B, C -->
|
|
507
|
+
<!-- Visual order desktop: B, A, C -->
|
|
508
|
+
<div class="col-4 col-order-2">A (DOM 1st, Visual 2nd)</div>
|
|
509
|
+
<div class="col-4 col-order-1">B (DOM 2nd, Visual 1st)</div>
|
|
510
|
+
<div class="col-4 col-order-3">C (DOM 3rd, Visual 3rd)</div>
|
|
511
|
+
</div>
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### ⚠️ CRITICAL ACCESSIBILITY WARNING
|
|
515
|
+
|
|
516
|
+
**The `order` property changes VISUAL order only, NOT DOM order.**
|
|
517
|
+
|
|
518
|
+
Screen readers and keyboard navigation follow DOM order, not visual order created by flexbox `order`.
|
|
519
|
+
|
|
520
|
+
```html
|
|
521
|
+
<div class="col-row">
|
|
522
|
+
<!-- Screen reader reads: "Column A", "Column B" -->
|
|
523
|
+
<!-- Visual display shows: "Column B", "Column A" -->
|
|
524
|
+
<div class="col-6 col-order-2">Column A</div>
|
|
525
|
+
<div class="col-6 col-order-1">Column B</div>
|
|
526
|
+
</div>
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**What users experience:**
|
|
530
|
+
|
|
531
|
+
- **Sighted users:** See "Column B" first, "Column A" second
|
|
532
|
+
- **Screen reader users:** Hear "Column A" first, "Column B" second
|
|
533
|
+
- **Keyboard users:** Tab order is "Column A" → "Column B" (DOM order)
|
|
534
|
+
|
|
535
|
+
**Best Practices:**
|
|
536
|
+
|
|
537
|
+
1. **NEVER** reorder critical content (navigation, forms, important actions)
|
|
538
|
+
2. **NEVER** create confusing tab order with visual reordering
|
|
539
|
+
3. **ONLY** use `order` for decorative or non-critical content
|
|
540
|
+
4. **ALWAYS** test with keyboard navigation (Tab order follows DOM)
|
|
541
|
+
5. **ALWAYS** test with screen readers (announcement order follows DOM)
|
|
542
|
+
|
|
543
|
+
**Safe Use Cases:**
|
|
544
|
+
|
|
545
|
+
- Reordering decorative cards or images
|
|
546
|
+
- Moving secondary content for visual balance
|
|
547
|
+
- Adjusting layout of non-interactive elements
|
|
548
|
+
|
|
549
|
+
**Unsafe Use Cases (NEVER DO THIS):**
|
|
550
|
+
|
|
551
|
+
```html
|
|
552
|
+
<!-- ❌ BAD: Confusing form tab order -->
|
|
553
|
+
<div class="col-row">
|
|
554
|
+
<button class="col-6 col-order-2">Submit</button>
|
|
555
|
+
<button class="col-6 col-order-1">Cancel</button>
|
|
556
|
+
<!-- Visual: Cancel, Submit | Tab order: Submit, Cancel -->
|
|
557
|
+
</div>
|
|
558
|
+
|
|
559
|
+
<!-- ✅ GOOD: Change DOM order instead -->
|
|
560
|
+
<div class="col-row">
|
|
561
|
+
<button class="col-6">Cancel</button>
|
|
562
|
+
<button class="col-6">Submit</button>
|
|
563
|
+
</div>
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
## Real-World Responsive Examples
|
|
567
|
+
|
|
568
|
+
### Dashboard Card Grid
|
|
569
|
+
|
|
570
|
+
Create a responsive dashboard with cards that adapt to screen size.
|
|
571
|
+
|
|
572
|
+
**Layout Progression:**
|
|
573
|
+
|
|
574
|
+
```
|
|
575
|
+
Mobile (< 768px): Tablet (≥ 768px): Desktop (≥ 1024px):
|
|
576
|
+
┌─────────────┐ ┌──────┬──────┐ ┌────┬────┬────┬────┐
|
|
577
|
+
│ Card 1 │ │ C1 │ C2 │ │ C1 │ C2 │ C3 │ C4 │
|
|
578
|
+
├─────────────┤ ├──────┼──────┤ └────┴────┴────┴────┘
|
|
579
|
+
│ Card 2 │ │ C3 │ C4 │
|
|
580
|
+
├─────────────┤ └──────┴──────┘
|
|
581
|
+
│ Card 3 │
|
|
582
|
+
├─────────────┤
|
|
583
|
+
│ Card 4 │
|
|
584
|
+
└─────────────┘
|
|
585
|
+
|
|
586
|
+
1 column 2 columns 4 columns
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
**HTML:**
|
|
590
|
+
|
|
591
|
+
```html
|
|
592
|
+
<div class="col-row">
|
|
593
|
+
<div class="col-12 col-md-6 col-lg-3">
|
|
594
|
+
<div class="card">
|
|
595
|
+
<h3>Total Users</h3>
|
|
596
|
+
<p>1,234</p>
|
|
597
|
+
</div>
|
|
598
|
+
</div>
|
|
599
|
+
<div class="col-12 col-md-6 col-lg-3">
|
|
600
|
+
<div class="card">
|
|
601
|
+
<h3>Revenue</h3>
|
|
602
|
+
<p>$12,345</p>
|
|
603
|
+
</div>
|
|
604
|
+
</div>
|
|
605
|
+
<div class="col-12 col-md-6 col-lg-3">
|
|
606
|
+
<div class="card">
|
|
607
|
+
<h3>Conversions</h3>
|
|
608
|
+
<p>567</p>
|
|
609
|
+
</div>
|
|
610
|
+
</div>
|
|
611
|
+
<div class="col-12 col-md-6 col-lg-3">
|
|
612
|
+
<div class="card">
|
|
613
|
+
<h3>Growth</h3>
|
|
614
|
+
<p>+23%</p>
|
|
615
|
+
</div>
|
|
616
|
+
</div>
|
|
617
|
+
</div>
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Blog Sidebar Layout
|
|
621
|
+
|
|
622
|
+
Content stacks on mobile, sidebar appears on tablet and larger screens.
|
|
623
|
+
|
|
624
|
+
**Layout Progression:**
|
|
625
|
+
|
|
626
|
+
```
|
|
627
|
+
Mobile (< 768px): Desktop (≥ 768px):
|
|
628
|
+
┌─────────────┐ ┌─────────┬───────┐
|
|
629
|
+
│ Content │ │ Content │ Side │
|
|
630
|
+
├─────────────┤ │ │ bar │
|
|
631
|
+
│ Sidebar │ │ │ │
|
|
632
|
+
└─────────────┘ └─────────┴───────┘
|
|
633
|
+
|
|
634
|
+
Stacked Side-by-side (66% / 33%)
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
**HTML:**
|
|
638
|
+
|
|
639
|
+
```html
|
|
640
|
+
<div class="col-row">
|
|
641
|
+
<div class="col-12 col-md-8">
|
|
642
|
+
<article>
|
|
643
|
+
<h1>Blog Post Title</h1>
|
|
644
|
+
<p>Main blog content...</p>
|
|
645
|
+
</article>
|
|
646
|
+
</div>
|
|
647
|
+
<div class="col-12 col-md-4">
|
|
648
|
+
<aside>
|
|
649
|
+
<h2>Recent Posts</h2>
|
|
650
|
+
<ul>
|
|
651
|
+
<li>Post 1</li>
|
|
652
|
+
<li>Post 2</li>
|
|
653
|
+
<li>Post 3</li>
|
|
654
|
+
</ul>
|
|
655
|
+
</aside>
|
|
656
|
+
</div>
|
|
657
|
+
</div>
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### Product Grid
|
|
661
|
+
|
|
662
|
+
Progressive grid: 1 column on mobile → 2 columns on tablet → 3 columns on desktop.
|
|
663
|
+
|
|
664
|
+
**HTML:**
|
|
665
|
+
|
|
666
|
+
```html
|
|
667
|
+
<div class="col-row">
|
|
668
|
+
<div class="col-12 col-sm-6 col-lg-4">
|
|
669
|
+
<div class="product-card">
|
|
670
|
+
<img src="product1.jpg" alt="Product 1" />
|
|
671
|
+
<h3>Product Name</h3>
|
|
672
|
+
<p>$29.99</p>
|
|
673
|
+
</div>
|
|
674
|
+
</div>
|
|
675
|
+
<div class="col-12 col-sm-6 col-lg-4">
|
|
676
|
+
<div class="product-card">
|
|
677
|
+
<img src="product2.jpg" alt="Product 2" />
|
|
678
|
+
<h3>Product Name</h3>
|
|
679
|
+
<p>$39.99</p>
|
|
680
|
+
</div>
|
|
681
|
+
</div>
|
|
682
|
+
<div class="col-12 col-sm-6 col-lg-4">
|
|
683
|
+
<div class="product-card">
|
|
684
|
+
<img src="product3.jpg" alt="Product 3" />
|
|
685
|
+
<h3>Product Name</h3>
|
|
686
|
+
<p>$49.99</p>
|
|
687
|
+
</div>
|
|
688
|
+
</div>
|
|
689
|
+
<div class="col-12 col-sm-6 col-lg-4">
|
|
690
|
+
<div class="product-card">
|
|
691
|
+
<img src="product4.jpg" alt="Product 4" />
|
|
692
|
+
<h3>Product Name</h3>
|
|
693
|
+
<p>$59.99</p>
|
|
694
|
+
</div>
|
|
695
|
+
</div>
|
|
696
|
+
<div class="col-12 col-sm-6 col-lg-4">
|
|
697
|
+
<div class="product-card">
|
|
698
|
+
<img src="product5.jpg" alt="Product 5" />
|
|
699
|
+
<h3>Product Name</h3>
|
|
700
|
+
<p>$69.99</p>
|
|
701
|
+
</div>
|
|
702
|
+
</div>
|
|
703
|
+
<div class="col-12 col-sm-6 col-lg-4">
|
|
704
|
+
<div class="product-card">
|
|
705
|
+
<img src="product6.jpg" alt="Product 6" />
|
|
706
|
+
<h3>Product Name</h3>
|
|
707
|
+
<p>$79.99</p>
|
|
708
|
+
</div>
|
|
709
|
+
</div>
|
|
710
|
+
</div>
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
**Result:**
|
|
714
|
+
|
|
715
|
+
- **Mobile** (< 480px): 1 column (100% width each)
|
|
716
|
+
- **Tablet** (≥ 480px): 2 columns (50% width each)
|
|
717
|
+
- **Desktop** (≥ 1024px): 3 columns (33.33% width each)
|
|
718
|
+
|
|
719
|
+
### Form Layout
|
|
720
|
+
|
|
721
|
+
Responsive multi-column form with smart field grouping.
|
|
722
|
+
|
|
723
|
+
**HTML:**
|
|
724
|
+
|
|
725
|
+
```html
|
|
726
|
+
<form>
|
|
727
|
+
<div class="col-row">
|
|
728
|
+
<!-- Full-width mobile, 2-col tablet -->
|
|
729
|
+
<div class="col-12 col-md-6">
|
|
730
|
+
<label for="firstName">First Name</label>
|
|
731
|
+
<input type="text" id="firstName" />
|
|
732
|
+
</div>
|
|
733
|
+
<div class="col-12 col-md-6">
|
|
734
|
+
<label for="lastName">Last Name</label>
|
|
735
|
+
<input type="text" id="lastName" />
|
|
736
|
+
</div>
|
|
737
|
+
|
|
738
|
+
<!-- Full-width email field -->
|
|
739
|
+
<div class="col-12">
|
|
740
|
+
<label for="email">Email</label>
|
|
741
|
+
<input type="email" id="email" />
|
|
742
|
+
</div>
|
|
743
|
+
|
|
744
|
+
<!-- 3-col address fields on desktop -->
|
|
745
|
+
<div class="col-12 col-md-6 col-lg-4">
|
|
746
|
+
<label for="city">City</label>
|
|
747
|
+
<input type="text" id="city" />
|
|
748
|
+
</div>
|
|
749
|
+
<div class="col-12 col-md-6 col-lg-4">
|
|
750
|
+
<label for="state">State</label>
|
|
751
|
+
<input type="text" id="state" />
|
|
752
|
+
</div>
|
|
753
|
+
<div class="col-12 col-lg-4">
|
|
754
|
+
<label for="zip">ZIP</label>
|
|
755
|
+
<input type="text" id="zip" />
|
|
756
|
+
</div>
|
|
757
|
+
|
|
758
|
+
<!-- Full-width submit -->
|
|
759
|
+
<div class="col-12">
|
|
760
|
+
<button type="submit">Submit</button>
|
|
761
|
+
</div>
|
|
762
|
+
</div>
|
|
763
|
+
</form>
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Centered Content with Progressive Margins
|
|
767
|
+
|
|
768
|
+
Content gets narrower and more centered as viewport increases.
|
|
769
|
+
|
|
770
|
+
**HTML:**
|
|
771
|
+
|
|
772
|
+
```html
|
|
773
|
+
<div class="col-row">
|
|
774
|
+
<div class="col-10 col-offset-1 col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3">
|
|
775
|
+
<article>
|
|
776
|
+
<h1>Article Title</h1>
|
|
777
|
+
<p>
|
|
778
|
+
This content progressively narrows and centers as the screen gets larger,
|
|
779
|
+
creating optimal reading width on all devices.
|
|
780
|
+
</p>
|
|
781
|
+
</article>
|
|
782
|
+
</div>
|
|
783
|
+
</div>
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
**Result:**
|
|
787
|
+
|
|
788
|
+
- **Mobile** (< 480px): 100% width, no margins
|
|
789
|
+
- **Small** (≥ 480px): 83.33% width (10/12), 8.33% left margin (1/12), 8.33% right (1/12)
|
|
790
|
+
- **Tablet** (≥ 768px): 66.67% width (8/12), 16.67% left margin (2/12), 16.67% right (2/12)
|
|
791
|
+
- **Desktop** (≥ 1024px): 50% width (6/12), 25% left margin (3/12), 25% right (3/12)
|
|
792
|
+
|
|
793
|
+
## Row Variant Utilities
|
|
794
|
+
|
|
795
|
+
### Gap Control
|
|
796
|
+
|
|
797
|
+
Control spacing between columns using gap utilities on the `.col-row` container.
|
|
798
|
+
|
|
799
|
+
| Class | Gap Size | Value | Use Case |
|
|
800
|
+
|-------|----------|-------|----------|
|
|
801
|
+
| `.col-row-gap-0` | None | `0` | No spacing |
|
|
802
|
+
| `.col-row-gap-xs` | Extra small | `var(--spacing-xs)` | Compact layouts |
|
|
803
|
+
| `.col-row-gap-sm` | Small | `var(--spacing-sm)` | Tight spacing |
|
|
804
|
+
| `.col-row-gap-md` | Medium (default) | `var(--spacing-md)` | Standard spacing |
|
|
805
|
+
| `.col-row-gap-lg` | Large | `var(--spacing-lg)` | Generous spacing |
|
|
806
|
+
| `.col-row-gap-xl` | Extra large | `var(--spacing-xl)` | Maximum spacing |
|
|
807
|
+
|
|
808
|
+
**Example:**
|
|
809
|
+
|
|
810
|
+
```html
|
|
811
|
+
<div class="col-row col-row-gap-lg">
|
|
812
|
+
<div class="col-6">Column with large gap</div>
|
|
813
|
+
<div class="col-6">Column with large gap</div>
|
|
814
|
+
</div>
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Justify Content
|
|
818
|
+
|
|
819
|
+
Control horizontal alignment of columns along the main axis.
|
|
820
|
+
|
|
821
|
+
| Class | Alignment | Behavior | Use Case |
|
|
822
|
+
|-------|-----------|----------|----------|
|
|
823
|
+
| `.col-row-justify-start` | Flex-start | Left-align columns | Default alignment |
|
|
824
|
+
| `.col-row-justify-center` | Center | Center columns | Center column group |
|
|
825
|
+
| `.col-row-justify-end` | Flex-end | Right-align columns | Right-align layout |
|
|
826
|
+
| `.col-row-justify-between` | Space-between | Max space between, edges flush | Spread columns |
|
|
827
|
+
| `.col-row-justify-around` | Space-around | Equal space around each | Even distribution |
|
|
828
|
+
| `.col-row-justify-evenly` | Space-evenly | Equal space between and edges | Perfect distribution |
|
|
829
|
+
|
|
830
|
+
**Example:**
|
|
831
|
+
|
|
832
|
+
```html
|
|
833
|
+
<!-- Center columns that don't fill full width -->
|
|
834
|
+
<div class="col-row col-row-justify-center">
|
|
835
|
+
<div class="col-3">Column</div>
|
|
836
|
+
<div class="col-3">Column</div>
|
|
837
|
+
</div>
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
### Align Items
|
|
841
|
+
|
|
842
|
+
Control vertical alignment of columns along the cross axis.
|
|
843
|
+
|
|
844
|
+
| Class | Alignment | Behavior | Use Case |
|
|
845
|
+
|-------|-----------|----------|----------|
|
|
846
|
+
| `.col-row-align-start` | Flex-start | Top-align | Align to top |
|
|
847
|
+
| `.col-row-align-center` | Center | Vertically center | Center content |
|
|
848
|
+
| `.col-row-align-end` | Flex-end | Bottom-align | Align to bottom |
|
|
849
|
+
| `.col-row-align-baseline` | Baseline | Text baseline align | Align text baselines |
|
|
850
|
+
| `.col-row-align-stretch` | Stretch | Equal heights | Match column heights |
|
|
851
|
+
|
|
852
|
+
**Example:**
|
|
853
|
+
|
|
854
|
+
```html
|
|
855
|
+
<!-- Vertically center columns with different heights -->
|
|
856
|
+
<div class="col-row col-row-align-center">
|
|
857
|
+
<div class="col-6">Short content</div>
|
|
858
|
+
<div class="col-6">
|
|
859
|
+
Much longer content that spans multiple lines...
|
|
860
|
+
</div>
|
|
861
|
+
</div>
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
### Wrap Control
|
|
865
|
+
|
|
866
|
+
Control how columns wrap within the container.
|
|
867
|
+
|
|
868
|
+
| Class | Behavior | Use Case |
|
|
869
|
+
|-------|----------|----------|
|
|
870
|
+
| `.col-row-nowrap` | Prevent wrapping | Force single row |
|
|
871
|
+
| `.col-row-wrap-reverse` | Wrap in reverse order | Reverse row stacking |
|
|
872
|
+
|
|
873
|
+
**Example:**
|
|
874
|
+
|
|
875
|
+
```html
|
|
876
|
+
<!-- Prevent columns from wrapping (may cause overflow) -->
|
|
877
|
+
<div class="col-row col-row-nowrap">
|
|
878
|
+
<div class="col-6">Column</div>
|
|
879
|
+
<div class="col-6">Column</div>
|
|
880
|
+
</div>
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
## Combining Utilities
|
|
884
|
+
|
|
885
|
+
### Multiple Breakpoints
|
|
886
|
+
|
|
887
|
+
Combine multiple responsive classes for fine-grained control:
|
|
888
|
+
|
|
889
|
+
```html
|
|
890
|
+
<!-- Different width at each breakpoint -->
|
|
891
|
+
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
|
|
892
|
+
Mobile: 100% → Tablet (480px): 50% → Desktop (768px): 33% → Large (1024px): 25%
|
|
893
|
+
</div>
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
### Size + Offset
|
|
897
|
+
|
|
898
|
+
Combine column spans with offsets for precise positioning:
|
|
899
|
+
|
|
900
|
+
```html
|
|
901
|
+
<!-- 6-column width, centered with 3-column offset -->
|
|
902
|
+
<div class="col-6 col-offset-3">
|
|
903
|
+
Centered column
|
|
904
|
+
</div>
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
### Size + Offset + Order
|
|
908
|
+
|
|
909
|
+
Complex positioning with all three utilities:
|
|
910
|
+
|
|
911
|
+
```html
|
|
912
|
+
<div class="col-4 col-offset-2 col-order-2">
|
|
913
|
+
33.33% width, 16.67% left margin, visual order 2
|
|
914
|
+
</div>
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
### Responsive Size + Responsive Offset
|
|
918
|
+
|
|
919
|
+
Progressive centering across breakpoints:
|
|
920
|
+
|
|
921
|
+
```html
|
|
922
|
+
<!-- Mobile: full width, Tablet: 8-col centered, Desktop: 6-col more centered -->
|
|
923
|
+
<div class="col-12 col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3">
|
|
924
|
+
Progressively centered content
|
|
925
|
+
</div>
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
### Row Utilities + Responsive Columns
|
|
929
|
+
|
|
930
|
+
Combine row utilities with responsive column classes:
|
|
931
|
+
|
|
932
|
+
```html
|
|
933
|
+
<div class="col-row col-row-gap-lg col-row-align-center">
|
|
934
|
+
<div class="col-12 col-md-6 col-lg-4">Column</div>
|
|
935
|
+
<div class="col-12 col-md-6 col-lg-4">Column</div>
|
|
936
|
+
<div class="col-12 col-md-6 col-lg-4">Column</div>
|
|
937
|
+
</div>
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
## Migration Guide
|
|
941
|
+
|
|
942
|
+
### From Bootstrap
|
|
943
|
+
|
|
944
|
+
Bootstrap and fpkit columns share similar 12-column grid concepts with some key differences.
|
|
945
|
+
|
|
946
|
+
| Bootstrap | fpkit Columns | Notes |
|
|
947
|
+
|-----------|---------------|-------|
|
|
948
|
+
| `.col-12` | `.col-12` | Same 100% width |
|
|
949
|
+
| `.col-sm-6` | `.col-sm-6` | Different breakpoint value |
|
|
950
|
+
| `.col-md-4` | `.col-md-4` | Same breakpoint (768px) |
|
|
951
|
+
| `.col-lg-3` | `.col-lg-3` | Different breakpoint value |
|
|
952
|
+
| `.offset-md-2` | `.col-md-offset-2` | Different prefix |
|
|
953
|
+
| `.order-md-1` | `.col-md-order-1` | Different prefix |
|
|
954
|
+
| `.col-md-auto` | `.col-md-auto` | Same auto-width |
|
|
955
|
+
|
|
956
|
+
**Bootstrap Breakpoints:**
|
|
957
|
+
|
|
958
|
+
- xs: 0px (default)
|
|
959
|
+
- sm: 576px
|
|
960
|
+
- md: 768px
|
|
961
|
+
- lg: 992px
|
|
962
|
+
- xl: 1200px
|
|
963
|
+
- xxl: 1400px
|
|
964
|
+
|
|
965
|
+
**fpkit Breakpoints:**
|
|
966
|
+
|
|
967
|
+
- xs: 0px (default)
|
|
968
|
+
- sm: 480px ← Different
|
|
969
|
+
- md: 768px ✓ Same
|
|
970
|
+
- lg: 1024px ← Different
|
|
971
|
+
|
|
972
|
+
**Key Differences:**
|
|
973
|
+
|
|
974
|
+
1. **Breakpoint values** - sm and lg differ between systems
|
|
975
|
+
2. **Class naming** - fpkit uses `col-md-offset-*` vs Bootstrap's `offset-md-*`
|
|
976
|
+
3. **Order prefix** - fpkit uses `col-md-order-*` vs Bootstrap's `order-md-*`
|
|
977
|
+
4. **Container** - Bootstrap uses `.container` or `.row`, fpkit uses `.col-row`
|
|
978
|
+
5. **Push/Pull** - Bootstrap has push/pull utilities, fpkit only has offset (use order for reordering)
|
|
979
|
+
|
|
980
|
+
### From Tailwind
|
|
981
|
+
|
|
982
|
+
Tailwind uses arbitrary fractional widths; fpkit uses a strict 12-column system.
|
|
983
|
+
|
|
984
|
+
| Tailwind | fpkit Columns | Notes |
|
|
985
|
+
|----------|---------------|-------|
|
|
986
|
+
| `.w-full` | `.col-12` | 100% width |
|
|
987
|
+
| `.w-1/2` | `.col-6` | 50% width |
|
|
988
|
+
| `.w-1/3` | `.col-4` | 33.33% width |
|
|
989
|
+
| `.w-1/4` | `.col-3` | 25% width |
|
|
990
|
+
| `.w-2/3` | `.col-8` | 66.67% width |
|
|
991
|
+
| `.w-3/4` | `.col-9` | 75% width |
|
|
992
|
+
| `.sm:w-1/2` | `.col-sm-6` | Responsive 50% |
|
|
993
|
+
| `.md:w-1/3` | `.col-md-4` | Responsive 33% |
|
|
994
|
+
| `.lg:w-1/4` | `.col-lg-3` | Responsive 25% |
|
|
995
|
+
|
|
996
|
+
**Tailwind Breakpoints:**
|
|
997
|
+
|
|
998
|
+
- sm: 640px
|
|
999
|
+
- md: 768px
|
|
1000
|
+
- lg: 1024px ✓ Same as fpkit
|
|
1001
|
+
- xl: 1280px
|
|
1002
|
+
- 2xl: 1536px
|
|
1003
|
+
|
|
1004
|
+
**fpkit Breakpoints:**
|
|
1005
|
+
|
|
1006
|
+
- sm: 480px ← Different
|
|
1007
|
+
- md: 768px ✓ Same
|
|
1008
|
+
- lg: 1024px ✓ Same
|
|
1009
|
+
|
|
1010
|
+
**Key Differences:**
|
|
1011
|
+
|
|
1012
|
+
1. **Width system** - Tailwind uses arbitrary fractions (1/2, 1/3, 2/5), fpkit uses strict 12-column grid
|
|
1013
|
+
2. **Breakpoint values** - sm differs
|
|
1014
|
+
3. **Container requirement** - fpkit requires `.col-row` flex container
|
|
1015
|
+
4. **Utility-first** - Tailwind is utility-first for everything, fpkit columns are just one utility system
|
|
1016
|
+
|
|
1017
|
+
**Conversion Strategy:**
|
|
1018
|
+
|
|
1019
|
+
Convert Tailwind fractions to 12-column equivalents:
|
|
1020
|
+
|
|
1021
|
+
- 1/2 = 6/12 → `.col-6`
|
|
1022
|
+
- 1/3 = 4/12 → `.col-4`
|
|
1023
|
+
- 2/3 = 8/12 → `.col-8`
|
|
1024
|
+
- 1/4 = 3/12 → `.col-3`
|
|
1025
|
+
- 3/4 = 9/12 → `.col-9`
|
|
1026
|
+
|
|
1027
|
+
### From Foundation
|
|
1028
|
+
|
|
1029
|
+
Foundation uses a similar 12-column grid with different naming conventions.
|
|
1030
|
+
|
|
1031
|
+
| Foundation | fpkit Columns | Notes |
|
|
1032
|
+
|------------|---------------|-------|
|
|
1033
|
+
| `.small-12` | `.col-12` | Base mobile width |
|
|
1034
|
+
| `.medium-6` | `.col-md-6` | Tablet width |
|
|
1035
|
+
| `.large-4` | `.col-lg-4` | Desktop width |
|
|
1036
|
+
| `.small-offset-2` | `.col-offset-2` | Offset differs |
|
|
1037
|
+
|
|
1038
|
+
**Foundation Breakpoints:**
|
|
1039
|
+
|
|
1040
|
+
- small: 0px (default)
|
|
1041
|
+
- medium: 640px
|
|
1042
|
+
- large: 1024px ✓ Same as fpkit lg
|
|
1043
|
+
|
|
1044
|
+
**fpkit Breakpoints:**
|
|
1045
|
+
|
|
1046
|
+
- xs: 0px (default)
|
|
1047
|
+
- sm: 480px
|
|
1048
|
+
- md: 768px
|
|
1049
|
+
- lg: 1024px ✓ Same
|
|
1050
|
+
|
|
1051
|
+
**Key Differences:**
|
|
1052
|
+
|
|
1053
|
+
1. **Class naming** - Foundation uses `.small-*`, fpkit uses `.col-*` for base and `.col-md-*` for responsive
|
|
1054
|
+
2. **Breakpoint values** - medium breakpoint differs (640px vs 768px)
|
|
1055
|
+
3. **Container** - Foundation uses `.row`, fpkit uses `.col-row`
|
|
1056
|
+
|
|
1057
|
+
## Accessibility Considerations
|
|
1058
|
+
|
|
1059
|
+
### Visual vs. DOM Order (CRITICAL)
|
|
1060
|
+
|
|
1061
|
+
**The `order` property changes visual order ONLY.**
|
|
1062
|
+
|
|
1063
|
+
Screen readers, keyboard navigation, and assistive technologies follow DOM order, not visual order.
|
|
1064
|
+
|
|
1065
|
+
**Example Problem:**
|
|
1066
|
+
|
|
1067
|
+
```html
|
|
1068
|
+
<div class="col-row">
|
|
1069
|
+
<!-- DOM order: Input 1, Input 2, Submit -->
|
|
1070
|
+
<!-- Visual order: Submit, Input 1, Input 2 -->
|
|
1071
|
+
<input type="text" class="col-4 col-order-2" id="input1" />
|
|
1072
|
+
<input type="text" class="col-4 col-order-3" id="input2" />
|
|
1073
|
+
<button class="col-4 col-order-1">Submit</button>
|
|
1074
|
+
</div>
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
**What happens:**
|
|
1078
|
+
|
|
1079
|
+
1. **Sighted users** see: Submit button → Input 1 → Input 2
|
|
1080
|
+
2. **Screen reader users** hear: Input 1 → Input 2 → Submit button
|
|
1081
|
+
3. **Keyboard users** tab: Input 1 → Input 2 → Submit button
|
|
1082
|
+
|
|
1083
|
+
This creates a **confusing and inaccessible experience** where visual order doesn't match interaction order.
|
|
1084
|
+
|
|
1085
|
+
**Solution: Change DOM Order**
|
|
1086
|
+
|
|
1087
|
+
```html
|
|
1088
|
+
<div class="col-row">
|
|
1089
|
+
<!-- DOM order matches visual order -->
|
|
1090
|
+
<button class="col-4">Submit</button>
|
|
1091
|
+
<input type="text" class="col-4" id="input1" />
|
|
1092
|
+
<input type="text" class="col-4" id="input2" />
|
|
1093
|
+
</div>
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
**Best Practices:**
|
|
1097
|
+
|
|
1098
|
+
1. ✅ **DO** use order for decorative elements (images, cards, badges)
|
|
1099
|
+
2. ✅ **DO** use order for non-interactive content
|
|
1100
|
+
3. ❌ **DON'T** use order for navigation links
|
|
1101
|
+
4. ❌ **DON'T** use order for form inputs and buttons
|
|
1102
|
+
5. ❌ **DON'T** use order for any interactive elements
|
|
1103
|
+
6. ❌ **DON'T** create confusing tab order
|
|
1104
|
+
|
|
1105
|
+
**Safe Example:**
|
|
1106
|
+
|
|
1107
|
+
```html
|
|
1108
|
+
<!-- ✅ SAFE: Decorative cards, no interaction -->
|
|
1109
|
+
<div class="col-row">
|
|
1110
|
+
<div class="col-4 col-order-2">
|
|
1111
|
+
<img src="photo2.jpg" alt="Photo 2" />
|
|
1112
|
+
</div>
|
|
1113
|
+
<div class="col-4 col-order-1">
|
|
1114
|
+
<img src="photo1.jpg" alt="Photo 1" />
|
|
1115
|
+
</div>
|
|
1116
|
+
<div class="col-4 col-order-3">
|
|
1117
|
+
<img src="photo3.jpg" alt="Photo 3" />
|
|
1118
|
+
</div>
|
|
1119
|
+
</div>
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
### Responsive Focus Order
|
|
1123
|
+
|
|
1124
|
+
When combining responsive classes with order utilities, ensure focus order remains logical at all breakpoints.
|
|
1125
|
+
|
|
1126
|
+
**Problem:**
|
|
1127
|
+
|
|
1128
|
+
```html
|
|
1129
|
+
<!-- Tab order changes at different screen sizes -->
|
|
1130
|
+
<div class="col-row">
|
|
1131
|
+
<button class="col-12 col-md-order-2">Save</button>
|
|
1132
|
+
<button class="col-12 col-md-order-1">Cancel</button>
|
|
1133
|
+
</div>
|
|
1134
|
+
```
|
|
1135
|
+
|
|
1136
|
+
**Result:**
|
|
1137
|
+
|
|
1138
|
+
- **Mobile**: Tab order is Save → Cancel (DOM order)
|
|
1139
|
+
- **Desktop**: Visual order is Cancel → Save (flexbox order)
|
|
1140
|
+
- **But Tab order is still**: Save → Cancel (DOM order!)
|
|
1141
|
+
|
|
1142
|
+
**Solution:** Keep DOM order consistent or avoid order on interactive elements.
|
|
1143
|
+
|
|
1144
|
+
### Semantic HTML
|
|
1145
|
+
|
|
1146
|
+
Use appropriate semantic elements for better accessibility:
|
|
1147
|
+
|
|
1148
|
+
```html
|
|
1149
|
+
<!-- ✅ GOOD: Semantic list -->
|
|
1150
|
+
<ul class="col-row">
|
|
1151
|
+
<li class="col-4">Item 1</li>
|
|
1152
|
+
<li class="col-4">Item 2</li>
|
|
1153
|
+
<li class="col-4">Item 3</li>
|
|
1154
|
+
</ul>
|
|
1155
|
+
|
|
1156
|
+
<!-- ✅ GOOD: Article sections -->
|
|
1157
|
+
<div class="col-row">
|
|
1158
|
+
<article class="col-8">Main content</article>
|
|
1159
|
+
<aside class="col-4">Sidebar</aside>
|
|
1160
|
+
</div>
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
## Browser Support
|
|
1164
|
+
|
|
1165
|
+
The column system relies on modern CSS features with excellent browser support.
|
|
1166
|
+
|
|
1167
|
+
### CSS Features Used
|
|
1168
|
+
|
|
1169
|
+
| Feature | Support | Notes |
|
|
1170
|
+
|---------|---------|-------|
|
|
1171
|
+
| **Flexbox** | All modern browsers, IE10+ | Core layout mechanism |
|
|
1172
|
+
| **Media Queries** | All modern browsers, IE9+ | Responsive breakpoints |
|
|
1173
|
+
| **CSS Custom Properties** | All modern browsers (NO IE11) | Breakpoint and width variables |
|
|
1174
|
+
| **Logical Properties** | Chrome 87+, Firefox 66+, Safari 14.1+ | `margin-inline-start` for offsets |
|
|
1175
|
+
|
|
1176
|
+
### Fallbacks
|
|
1177
|
+
|
|
1178
|
+
**For IE11 (no CSS custom properties):**
|
|
1179
|
+
|
|
1180
|
+
The column widths will still work as percentages are defined in media queries, but JavaScript access to breakpoint variables won't work.
|
|
1181
|
+
|
|
1182
|
+
**For older browsers (no logical properties):**
|
|
1183
|
+
|
|
1184
|
+
Use directional properties as fallback:
|
|
1185
|
+
|
|
1186
|
+
```css
|
|
1187
|
+
/* Fallback for browsers without logical properties */
|
|
1188
|
+
.col-offset-3 {
|
|
1189
|
+
margin-left: 25%; /* Fallback */
|
|
1190
|
+
margin-inline-start: 25%; /* Modern browsers */
|
|
1191
|
+
}
|
|
1192
|
+
```
|
|
1193
|
+
|
|
1194
|
+
## Troubleshooting
|
|
1195
|
+
|
|
1196
|
+
### Columns Not Wrapping
|
|
1197
|
+
|
|
1198
|
+
**Problem:** Columns stay on one line instead of wrapping to new rows.
|
|
1199
|
+
|
|
1200
|
+
**Cause:** Missing `flex-wrap: wrap` on container.
|
|
1201
|
+
|
|
1202
|
+
**Solution:**
|
|
1203
|
+
|
|
1204
|
+
```html
|
|
1205
|
+
<!-- ❌ WRONG: Missing flex-wrap -->
|
|
1206
|
+
<div style="display: flex;">
|
|
1207
|
+
<div class="col-6">Column</div>
|
|
1208
|
+
<div class="col-6">Column</div>
|
|
1209
|
+
</div>
|
|
1210
|
+
|
|
1211
|
+
<!-- ✅ CORRECT: Add .col-row class -->
|
|
1212
|
+
<div class="col-row">
|
|
1213
|
+
<div class="col-6">Column</div>
|
|
1214
|
+
<div class="col-6">Column</div>
|
|
1215
|
+
</div>
|
|
1216
|
+
```
|
|
1217
|
+
|
|
1218
|
+
### Responsive Classes Not Applying
|
|
1219
|
+
|
|
1220
|
+
**Problem:** `.col-md-6` doesn't activate on tablet-sized screens.
|
|
1221
|
+
|
|
1222
|
+
**Cause:** Missing base class or viewport width below breakpoint.
|
|
1223
|
+
|
|
1224
|
+
**Solution:**
|
|
1225
|
+
|
|
1226
|
+
```html
|
|
1227
|
+
<!-- ❌ WRONG: Missing base class -->
|
|
1228
|
+
<div class="col-md-6">Column</div>
|
|
1229
|
+
|
|
1230
|
+
<!-- ✅ CORRECT: Include base class for mobile -->
|
|
1231
|
+
<div class="col-12 col-md-6">Column</div>
|
|
1232
|
+
```
|
|
1233
|
+
|
|
1234
|
+
**Also check:**
|
|
1235
|
+
|
|
1236
|
+
- Actual viewport width (use DevTools)
|
|
1237
|
+
- md breakpoint is 768px (48rem)
|
|
1238
|
+
- Browser zoom level (affects viewport width)
|
|
1239
|
+
|
|
1240
|
+
### Columns Always 100% Width
|
|
1241
|
+
|
|
1242
|
+
**Problem:** Columns don't spread horizontally even on desktop.
|
|
1243
|
+
|
|
1244
|
+
**Cause:** Viewport width is below the breakpoint (< 768px for base columns).
|
|
1245
|
+
|
|
1246
|
+
**Solution:**
|
|
1247
|
+
|
|
1248
|
+
- Verify actual viewport size in DevTools
|
|
1249
|
+
- Base `.col-*` classes activate at ≥ 768px (48rem)
|
|
1250
|
+
- Use `.col-sm-*` for smaller screens (≥ 480px)
|
|
1251
|
+
- Check for CSS overrides with higher specificity
|
|
1252
|
+
|
|
1253
|
+
### Gap Not Working
|
|
1254
|
+
|
|
1255
|
+
**Problem:** No space between columns.
|
|
1256
|
+
|
|
1257
|
+
**Cause:** Container missing `gap` property or browser doesn't support flexbox gap.
|
|
1258
|
+
|
|
1259
|
+
**Solution:**
|
|
1260
|
+
|
|
1261
|
+
```html
|
|
1262
|
+
<!-- ✅ CORRECT: .col-row includes gap by default -->
|
|
1263
|
+
<div class="col-row">
|
|
1264
|
+
<div class="col-6">Column</div>
|
|
1265
|
+
<div class="col-6">Column</div>
|
|
1266
|
+
</div>
|
|
1267
|
+
|
|
1268
|
+
<!-- OR: Customize gap -->
|
|
1269
|
+
<div class="col-row col-row-gap-lg">
|
|
1270
|
+
<div class="col-6">Column</div>
|
|
1271
|
+
<div class="col-6">Column</div>
|
|
1272
|
+
</div>
|
|
1273
|
+
```
|
|
1274
|
+
|
|
1275
|
+
### Debugging Tips
|
|
1276
|
+
|
|
1277
|
+
**1. Use DevTools Responsive Mode:**
|
|
1278
|
+
|
|
1279
|
+
- Open DevTools (F12)
|
|
1280
|
+
- Click device toolbar icon (Ctrl+Shift+M / Cmd+Shift+M)
|
|
1281
|
+
- Select responsive mode
|
|
1282
|
+
- Resize viewport to test breakpoints
|
|
1283
|
+
|
|
1284
|
+
**2. Inspect Computed Styles:**
|
|
1285
|
+
|
|
1286
|
+
```javascript
|
|
1287
|
+
// Check which class is active
|
|
1288
|
+
const el = document.querySelector('.col-12');
|
|
1289
|
+
const styles = getComputedStyle(el);
|
|
1290
|
+
console.log('flex:', styles.flex);
|
|
1291
|
+
console.log('max-width:', styles.maxWidth);
|
|
1292
|
+
```
|
|
1293
|
+
|
|
1294
|
+
**3. Test Breakpoints:**
|
|
1295
|
+
|
|
1296
|
+
Common device widths to test:
|
|
1297
|
+
|
|
1298
|
+
- **Mobile:** 375px (iPhone), 360px (Android)
|
|
1299
|
+
- **Tablet:** 768px (iPad portrait), 1024px (iPad landscape)
|
|
1300
|
+
- **Desktop:** 1280px (laptop), 1920px (monitor)
|
|
1301
|
+
|
|
1302
|
+
**4. Verify Container:**
|
|
1303
|
+
|
|
1304
|
+
```javascript
|
|
1305
|
+
// Check if container has flex-wrap
|
|
1306
|
+
const container = document.querySelector('.col-row');
|
|
1307
|
+
console.log('display:', getComputedStyle(container).display);
|
|
1308
|
+
console.log('flex-wrap:', getComputedStyle(container).flexWrap);
|
|
1309
|
+
```
|
|
1310
|
+
|
|
1311
|
+
## Performance Tips
|
|
1312
|
+
|
|
1313
|
+
### Minimize Class Churn
|
|
1314
|
+
|
|
1315
|
+
Avoid redundant responsive classes that don't change behavior.
|
|
1316
|
+
|
|
1317
|
+
**❌ AVOID:**
|
|
1318
|
+
|
|
1319
|
+
```html
|
|
1320
|
+
<!-- Redundant: col-sm-12 is same as mobile default -->
|
|
1321
|
+
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
|
|
1322
|
+
Column
|
|
1323
|
+
</div>
|
|
1324
|
+
```
|
|
1325
|
+
|
|
1326
|
+
**✅ PREFER:**
|
|
1327
|
+
|
|
1328
|
+
```html
|
|
1329
|
+
<!-- Cleaner: Only specify when width changes -->
|
|
1330
|
+
<div class="col-12 col-md-6">
|
|
1331
|
+
Column
|
|
1332
|
+
</div>
|
|
1333
|
+
```
|
|
1334
|
+
|
|
1335
|
+
### Use Semantic Breakpoints
|
|
1336
|
+
|
|
1337
|
+
Choose breakpoints based on content needs, not specific devices.
|
|
1338
|
+
|
|
1339
|
+
**✅ GOOD:**
|
|
1340
|
+
|
|
1341
|
+
```html
|
|
1342
|
+
<!-- Breakpoint chosen based on when layout needs to change -->
|
|
1343
|
+
<div class="col-12 col-md-8">
|
|
1344
|
+
Content becomes too narrow below 768px
|
|
1345
|
+
</div>
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
### Prefer CSS Over JavaScript
|
|
1349
|
+
|
|
1350
|
+
Let media queries handle responsive behavior instead of JavaScript resize listeners.
|
|
1351
|
+
|
|
1352
|
+
**❌ AVOID:**
|
|
1353
|
+
|
|
1354
|
+
```javascript
|
|
1355
|
+
// Don't use JS for responsive layout
|
|
1356
|
+
window.addEventListener('resize', () => {
|
|
1357
|
+
if (window.innerWidth >= 768) {
|
|
1358
|
+
element.classList.add('col-md-6');
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
```
|
|
1362
|
+
|
|
1363
|
+
**✅ PREFER:**
|
|
1364
|
+
|
|
1365
|
+
```html
|
|
1366
|
+
<!-- Let CSS handle it -->
|
|
1367
|
+
<div class="col-12 col-md-6">
|
|
1368
|
+
Responsive column
|
|
1369
|
+
</div>
|
|
1370
|
+
```
|
|
1371
|
+
|
|
1372
|
+
## Related Resources
|
|
1373
|
+
|
|
1374
|
+
- **[Col React Component README](./README.mdx)** - React component API and usage
|
|
1375
|
+
- **[Row Component](../row/README.mdx)** - Flex container component for columns
|
|
1376
|
+
- **[Grid Component](../grid/README.mdx)** - Alternative CSS Grid-based layout
|
|
1377
|
+
- **[MDN: Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout)** - CSS flexbox documentation
|
|
1378
|
+
- **[MDN: Media Queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries)** - Responsive breakpoints
|
|
1379
|
+
- **[CSS Tricks: A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)** - Flexbox reference
|
|
1380
|
+
- **[W3C: Flexbox Spec](https://www.w3.org/TR/css-flexbox-1/)** - Official specification
|