strata-css 1.0.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 +62 -0
- package/LICENSE +21 -0
- package/README.md +730 -0
- package/bin/strata.js +139 -0
- package/index.d.ts +70 -0
- package/package.json +68 -0
- package/src/components/modules/modal.js +123 -0
- package/src/components/modules/skeleton.js +334 -0
- package/src/components/strata.manifest.js +15 -0
- package/src/generator/generator.js +113 -0
- package/src/index.js +172 -0
- package/src/layers/base.js +571 -0
- package/src/registry/breakpoints.js +54 -0
- package/src/registry/registry.js +2898 -0
- package/src/scanner/scanner.js +106 -0
- package/strata.css +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# Strata CSS
|
|
4
|
+
|
|
5
|
+
**A modern CSS framework combining Bootstrap's component architecture with Tailwind's JIT processing.**
|
|
6
|
+
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[]()
|
|
9
|
+
[]()
|
|
10
|
+
[](https://www.npmjs.com/package/strata-css)
|
|
11
|
+
[]()
|
|
12
|
+
[]()
|
|
13
|
+
[]()
|
|
14
|
+
[]()
|
|
15
|
+
|
|
16
|
+
`css-framework` · `tailwindcss` · `bootstrap` · `postcss` · `postcss-plugin` · `jit` · `component-library` · `theming` · `utility-first`
|
|
17
|
+
|
|
18
|
+
[Getting Started](#getting-started) · [Live Demo](#live-demo) · [Components](#components) · [Utilities](#utilities) · [Theming](#theming) · [Configuration](#configuration)
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## What is Strata?
|
|
25
|
+
|
|
26
|
+
Strata is an open source CSS framework that takes the best from Bootstrap and Tailwind while fixing their biggest pain points.
|
|
27
|
+
|
|
28
|
+
**From Bootstrap** — component-first classes (`btn-primary`, `card`, `navbar`) that work out of the box with zero configuration.
|
|
29
|
+
|
|
30
|
+
**From Tailwind** — JIT post-processing that generates only the CSS you actually use, keeping output lean.
|
|
31
|
+
|
|
32
|
+
**Strata's own contributions:**
|
|
33
|
+
- No `!important` anywhere in framework CSS — `@layer` handles all specificity
|
|
34
|
+
- Custom CSS is fully compatible and always wins automatically
|
|
35
|
+
- Three built-in themes: light, dark, and dim — plus unlimited custom themes
|
|
36
|
+
- Buttery smooth transitions built in by default on all interactive elements
|
|
37
|
+
- State management via `data-st-*` attributes — no class toggling in JavaScript
|
|
38
|
+
- Arbitrary value utilities — `mt-[24px]`, `bg-[#ff0000]`, `w-[347px]`
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Benchmarks
|
|
43
|
+
|
|
44
|
+
Strata outperforms Tailwind on every metric in watch mode — the speed developers actually feel on every file save.
|
|
45
|
+
|
|
46
|
+
| Metric | Strata | Tailwind |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| Cold build average | 1.89ms | 7.21ms |
|
|
49
|
+
| Cold build median | 0.15ms | 4.55ms |
|
|
50
|
+
| Warm rebuild average | 0.14ms | 2.70ms |
|
|
51
|
+
| Warm rebuild p95 | 0.23ms | 6.12ms |
|
|
52
|
+
|
|
53
|
+
Results generated via `npm run benchmark`. See [`benchmark/`](./benchmark/) for the reproducible script.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Live Demo
|
|
58
|
+
|
|
59
|
+
View the interactive component showcase: [aftabibrahimkazi.github.io/strata](https://aftabibrahimkazi.github.io/strata)
|
|
60
|
+
|
|
61
|
+
To view locally: open `docs/index.html` directly in a browser — no build step required.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Getting Started
|
|
66
|
+
|
|
67
|
+
### Installation
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install strata-css
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
> **Publishing:** Run `npm publish --dry-run` to verify the package contents, then `npm publish` to release.
|
|
74
|
+
|
|
75
|
+
### Scaffold a new project
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx strata init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This creates:
|
|
82
|
+
```
|
|
83
|
+
strata.config.js ← configuration
|
|
84
|
+
strata.css ← entry point with @strata directives
|
|
85
|
+
postcss.config.js ← PostCSS setup
|
|
86
|
+
dist/ ← generated CSS output
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Link the output CSS in your HTML
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<link rel="stylesheet" href="dist/strata.output.css">
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Set a theme on your HTML element
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<html data-st-theme="light">
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Run in development
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm run dev
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Build for production
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run build
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## How It Works
|
|
116
|
+
|
|
117
|
+
Strata is a PostCSS plugin. It scans your source files for class names and generates only the CSS those classes need — nothing more.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Source files (HTML/JSX/Vue/Astro)
|
|
121
|
+
↓
|
|
122
|
+
Scanner (extracts class names)
|
|
123
|
+
↓
|
|
124
|
+
Registry (O(1) Map lookup)
|
|
125
|
+
↓
|
|
126
|
+
Generator (builds CSS)
|
|
127
|
+
↓
|
|
128
|
+
@layer st-base, st-components, st-utilities
|
|
129
|
+
↓
|
|
130
|
+
Output CSS
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Your custom CSS lives outside any layer and automatically wins over Strata styles — no `!important` needed.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Components
|
|
138
|
+
|
|
139
|
+
Components are full Bootstrap-style classes with states baked in. They live in `@layer st-components` so your custom CSS always overrides them.
|
|
140
|
+
|
|
141
|
+
### Buttons
|
|
142
|
+
|
|
143
|
+
```html
|
|
144
|
+
<button class="btn-primary">Primary</button>
|
|
145
|
+
<button class="btn-secondary">Secondary</button>
|
|
146
|
+
<button class="btn-success">Success</button>
|
|
147
|
+
<button class="btn-danger">Danger</button>
|
|
148
|
+
<button class="btn-warning">Warning</button>
|
|
149
|
+
<button class="btn-info">Info</button>
|
|
150
|
+
<button class="btn-light">Light</button>
|
|
151
|
+
<button class="btn-dark">Dark</button>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Layout
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<div class="container">
|
|
158
|
+
<div class="row">
|
|
159
|
+
<div class="col-md-6 col-lg-4">Column</div>
|
|
160
|
+
<div class="col-md-6 col-lg-8">Column</div>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Cards
|
|
166
|
+
|
|
167
|
+
```html
|
|
168
|
+
<div class="card">
|
|
169
|
+
<div class="card-header">Header</div>
|
|
170
|
+
<div class="card-body">Body</div>
|
|
171
|
+
<div class="card-footer">Footer</div>
|
|
172
|
+
</div>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Utilities
|
|
178
|
+
|
|
179
|
+
Utilities follow Bootstrap's naming convention and support arbitrary values via Tailwind-style syntax.
|
|
180
|
+
|
|
181
|
+
### Spacing
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
<!-- Scale values (0-5) -->
|
|
185
|
+
<div class="mt-3 mb-2 px-4 py-1">
|
|
186
|
+
<div class="mx-auto my-3">
|
|
187
|
+
|
|
188
|
+
<!-- Arbitrary values -->
|
|
189
|
+
<div class="mt-[24px] px-[1.5rem]">
|
|
190
|
+
|
|
191
|
+
<!-- Important variants -->
|
|
192
|
+
<div class="!mt-0 !mb-0">
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Display
|
|
196
|
+
|
|
197
|
+
```html
|
|
198
|
+
<div class="d-flex">
|
|
199
|
+
<div class="d-none">
|
|
200
|
+
<div class="d-block">
|
|
201
|
+
<div class="d-grid">
|
|
202
|
+
|
|
203
|
+
<!-- Responsive -->
|
|
204
|
+
<div class="d-none d-md-flex">
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Colours
|
|
208
|
+
|
|
209
|
+
```html
|
|
210
|
+
<!-- Text -->
|
|
211
|
+
<p class="text-primary">
|
|
212
|
+
<p class="text-[#ff0000]">
|
|
213
|
+
|
|
214
|
+
<!-- Background -->
|
|
215
|
+
<div class="bg-success">
|
|
216
|
+
<div class="bg-[rgba(0,0,0,0.5)]">
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Theming
|
|
222
|
+
|
|
223
|
+
### Built-in themes
|
|
224
|
+
|
|
225
|
+
```html
|
|
226
|
+
<html data-st-theme="light"> <!-- default -->
|
|
227
|
+
<html data-st-theme="dark"> <!-- dark mode -->
|
|
228
|
+
<html data-st-theme="dim"> <!-- intermediate -->
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### System preference
|
|
232
|
+
|
|
233
|
+
If no `data-st-theme` is set, Strata automatically follows the user's system preference via `prefers-color-scheme`.
|
|
234
|
+
|
|
235
|
+
### Custom theme
|
|
236
|
+
|
|
237
|
+
```css
|
|
238
|
+
[data-st-theme="brand"] {
|
|
239
|
+
--st-primary: #7c3aed;
|
|
240
|
+
--st-bg: #0f0f0f;
|
|
241
|
+
--st-text: #fafafa;
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```html
|
|
246
|
+
<html data-st-theme="brand">
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Switch theme with JavaScript
|
|
250
|
+
|
|
251
|
+
```js
|
|
252
|
+
document.documentElement.setAttribute('data-st-theme', 'dark')
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Theme Toggle
|
|
256
|
+
|
|
257
|
+
Cycle through all built-in themes with a single button — no framework needed.
|
|
258
|
+
|
|
259
|
+
```html
|
|
260
|
+
<button id="theme-toggle">Toggle Theme</button>
|
|
261
|
+
|
|
262
|
+
<script>
|
|
263
|
+
const themes = ['light', 'dark', 'dim']
|
|
264
|
+
let current = 0
|
|
265
|
+
|
|
266
|
+
document.getElementById('theme-toggle').addEventListener('click', () => {
|
|
267
|
+
current = (current + 1) % themes.length
|
|
268
|
+
document.documentElement.setAttribute('data-st-theme', themes[current])
|
|
269
|
+
})
|
|
270
|
+
</script>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
To start from the user's current theme rather than always resetting to `light`, read the attribute first:
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
const themes = ['light', 'dark', 'dim']
|
|
277
|
+
const initial = document.documentElement.getAttribute('data-st-theme') || 'light'
|
|
278
|
+
let current = themes.indexOf(initial)
|
|
279
|
+
if (current === -1) current = 0
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
To include your own custom themes in the cycle, add them to the array:
|
|
283
|
+
|
|
284
|
+
```js
|
|
285
|
+
const themes = ['light', 'dark', 'dim', 'brand']
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Any theme in the array must have its CSS variables defined before it can be toggled to:
|
|
289
|
+
|
|
290
|
+
```css
|
|
291
|
+
[data-st-theme="brand"] {
|
|
292
|
+
--st-primary: #7c3aed;
|
|
293
|
+
--st-bg: #0f0f0f;
|
|
294
|
+
--st-text: #fafafa;
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Override CSS variables
|
|
299
|
+
|
|
300
|
+
```css
|
|
301
|
+
:root {
|
|
302
|
+
--st-primary: #7c3aed;
|
|
303
|
+
--st-border-radius: 8px;
|
|
304
|
+
--st-duration: 300ms;
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Transitions
|
|
311
|
+
|
|
312
|
+
Strata builds smooth transitions into every interactive element by default.
|
|
313
|
+
|
|
314
|
+
### Control globally
|
|
315
|
+
|
|
316
|
+
```css
|
|
317
|
+
/* Slow all transitions */
|
|
318
|
+
:root { --st-duration: 400ms; }
|
|
319
|
+
|
|
320
|
+
/* Kill all transitions */
|
|
321
|
+
:root { --st-duration: 0ms; }
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Control per component
|
|
325
|
+
|
|
326
|
+
```css
|
|
327
|
+
.btn-primary { --st-duration: 80ms; }
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Transition utilities
|
|
331
|
+
|
|
332
|
+
```html
|
|
333
|
+
<div class="transition">
|
|
334
|
+
<div class="transition-fast">
|
|
335
|
+
<div class="transition-slow">
|
|
336
|
+
<div class="transition-none">
|
|
337
|
+
<div class="transition-[background-color_0.3s_ease]">
|
|
338
|
+
<div class="duration-[400ms]">
|
|
339
|
+
<div class="ease-in">
|
|
340
|
+
<div class="ease-out">
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Reduced motion
|
|
344
|
+
|
|
345
|
+
Strata automatically respects `prefers-reduced-motion` — no configuration needed.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## State Management
|
|
350
|
+
|
|
351
|
+
States are managed via `data-st-*` attributes. JavaScript sets the attribute, CSS handles the visual change.
|
|
352
|
+
|
|
353
|
+
```html
|
|
354
|
+
<!-- Visibility with fade transition -->
|
|
355
|
+
<div data-st-visible="true">Visible</div>
|
|
356
|
+
<div data-st-visible="false">Hidden (faded out)</div>
|
|
357
|
+
|
|
358
|
+
<!-- Collapse with smooth height transition -->
|
|
359
|
+
<div data-st-collapsed="false">Expanded</div>
|
|
360
|
+
<div data-st-collapsed="true">Collapsed</div>
|
|
361
|
+
|
|
362
|
+
<!-- Loading state -->
|
|
363
|
+
<button data-st-loading="true">Loading...</button>
|
|
364
|
+
|
|
365
|
+
<!-- Disabled state -->
|
|
366
|
+
<button data-st-disabled="true">Disabled</button>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
```js
|
|
370
|
+
// Toggle visibility
|
|
371
|
+
element.setAttribute('data-st-visible', 'false')
|
|
372
|
+
|
|
373
|
+
// Collapse/expand
|
|
374
|
+
element.setAttribute('data-st-collapsed', 'true')
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Skeleton Loader
|
|
380
|
+
|
|
381
|
+
Skeleton loading shows animated shimmer placeholders while content is fetching — preventing layout shift and giving users instant visual feedback that something is coming.
|
|
382
|
+
|
|
383
|
+
Strata's skeleton system is entirely attribute-driven. There are no class names to add. Instead, set `data-st-skeleton` on your elements and use the `Strata.skeleton` JS utility to manage the lifecycle.
|
|
384
|
+
|
|
385
|
+
### Attribute states
|
|
386
|
+
|
|
387
|
+
| Value | Meaning |
|
|
388
|
+
|---|---|
|
|
389
|
+
| `"true"` | Element shimmers (CSS applies animated `::before` overlay) |
|
|
390
|
+
| `"false"` | Element revealed (shimmer removed, content shows) |
|
|
391
|
+
| `"null"` | JS-managed parent — no overlay on the parent itself, children shimmer individually |
|
|
392
|
+
|
|
393
|
+
### Basic usage
|
|
394
|
+
|
|
395
|
+
Mark a container and call `Strata.skeleton.init()` — Strata auto-detects the leaf nodes inside and shimmers them individually.
|
|
396
|
+
|
|
397
|
+
```html
|
|
398
|
+
<div class="card" data-st-skeleton="true">
|
|
399
|
+
<div class="card-header">
|
|
400
|
+
<h3>Card Title</h3>
|
|
401
|
+
</div>
|
|
402
|
+
<div class="card-body">
|
|
403
|
+
<p>Some body text that will load soon.</p>
|
|
404
|
+
<button class="btn-primary">Action</button>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
```js
|
|
410
|
+
// Initialise — auto-detects leaf nodes inside all [data-st-skeleton="true"] parents
|
|
411
|
+
Strata.skeleton.init()
|
|
412
|
+
|
|
413
|
+
// Simulate data loading, then reveal
|
|
414
|
+
fetchData().then(() => {
|
|
415
|
+
Strata.skeleton.reveal()
|
|
416
|
+
})
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### JS API
|
|
420
|
+
|
|
421
|
+
```js
|
|
422
|
+
Strata.skeleton.init() // auto-discover all skeleton parents on page
|
|
423
|
+
Strata.skeleton.init('.card') // manage specific elements
|
|
424
|
+
Strata.skeleton.show('.card') // re-enter skeleton state
|
|
425
|
+
Strata.skeleton.reveal('.card') // reveal content (removes shimmer)
|
|
426
|
+
Strata.skeleton.toggle('.card') // toggle between skeleton and revealed
|
|
427
|
+
Strata.skeleton.revealAt('.card', 0) // reveal one element by index
|
|
428
|
+
Strata.skeleton.isSkeleton(el) // returns true if element is currently shimmering
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Staggered reveal
|
|
432
|
+
|
|
433
|
+
Reveal a list of cards one by one with a delay between each:
|
|
434
|
+
|
|
435
|
+
```js
|
|
436
|
+
Strata.skeleton.reveal('.card', { stagger: 150 })
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Opt out a child element
|
|
440
|
+
|
|
441
|
+
Set `data-st-skeleton="false"` on any child to exclude it from shimmering entirely:
|
|
442
|
+
|
|
443
|
+
```html
|
|
444
|
+
<div class="card" data-st-skeleton="true">
|
|
445
|
+
<div class="card-header">
|
|
446
|
+
<h3>Title</h3>
|
|
447
|
+
<span data-st-skeleton="false">Always visible badge</span>
|
|
448
|
+
</div>
|
|
449
|
+
</div>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Customise the shimmer
|
|
453
|
+
|
|
454
|
+
Control the shimmer appearance via CSS variables:
|
|
455
|
+
|
|
456
|
+
```css
|
|
457
|
+
:root {
|
|
458
|
+
--st-skeleton-base: #e2e8f0; /* bar background colour */
|
|
459
|
+
--st-skeleton-shine: #f8fafc; /* highlight colour */
|
|
460
|
+
--st-skeleton-duration: 1.5s; /* animation speed */
|
|
461
|
+
--st-skeleton-radius: 4px; /* corner rounding on bars */
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Realistic card example
|
|
466
|
+
|
|
467
|
+
A card that shimmers while data loads, then transitions to real content:
|
|
468
|
+
|
|
469
|
+
```html
|
|
470
|
+
<div class="card" id="profile-card" data-st-skeleton="true">
|
|
471
|
+
<div class="card-header">
|
|
472
|
+
<div class="img-wrap">
|
|
473
|
+
<img src="" alt="Avatar" id="avatar">
|
|
474
|
+
</div>
|
|
475
|
+
<h3 id="name"></h3>
|
|
476
|
+
</div>
|
|
477
|
+
<div class="card-body">
|
|
478
|
+
<p id="bio"></p>
|
|
479
|
+
<a href="#" id="profile-link" class="btn-primary">View Profile</a>
|
|
480
|
+
</div>
|
|
481
|
+
</div>
|
|
482
|
+
|
|
483
|
+
<script>
|
|
484
|
+
Strata.skeleton.init('#profile-card')
|
|
485
|
+
|
|
486
|
+
loadUser(42).then(user => {
|
|
487
|
+
document.getElementById('avatar').src = user.avatarUrl
|
|
488
|
+
document.getElementById('name').textContent = user.name
|
|
489
|
+
document.getElementById('bio').textContent = user.bio
|
|
490
|
+
document.getElementById('profile-link').href = user.profileUrl
|
|
491
|
+
|
|
492
|
+
Strata.skeleton.reveal('#profile-card')
|
|
493
|
+
})
|
|
494
|
+
</script>
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
> **Note on images:** Browsers do not support `::before` on replaced elements (`img`, `video`, `iframe`). Wrap media in a `div` — Strata will shimmer the wrapper instead.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## Custom CSS
|
|
502
|
+
|
|
503
|
+
Strata uses CSS `@layer` internally. Any CSS you write outside a layer automatically wins over Strata styles.
|
|
504
|
+
|
|
505
|
+
```css
|
|
506
|
+
/* This overrides Strata's .btn-primary — no !important needed */
|
|
507
|
+
.btn-primary {
|
|
508
|
+
background-color: purple;
|
|
509
|
+
border-radius: 0;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* Only overrides what you specify — other properties stay from Strata */
|
|
513
|
+
.card {
|
|
514
|
+
border-radius: 16px; /* changed */
|
|
515
|
+
/* padding, shadow etc. stay as Strata defined */
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
## JavaScript Integration
|
|
522
|
+
|
|
523
|
+
### Class naming convention
|
|
524
|
+
|
|
525
|
+
Classes used in JavaScript carry a `-js` suffix. Classes used in TypeScript carry a `-ts` suffix. This signals to any developer reading the code that the element is touched by a script.
|
|
526
|
+
|
|
527
|
+
```html
|
|
528
|
+
<div class="modal-js" id="main-modal-js">
|
|
529
|
+
<div class="modal-ts" id="main-modal-ts">
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Never toggle classes for state
|
|
533
|
+
|
|
534
|
+
```js
|
|
535
|
+
// Wrong — don't do this
|
|
536
|
+
element.classList.add('hidden')
|
|
537
|
+
element.classList.toggle('active')
|
|
538
|
+
|
|
539
|
+
// Right — use data attributes
|
|
540
|
+
element.setAttribute('data-st-visible', 'false')
|
|
541
|
+
element.setAttribute('data-st-active', 'true')
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
## Configuration
|
|
547
|
+
|
|
548
|
+
```js
|
|
549
|
+
// strata.config.js
|
|
550
|
+
module.exports = {
|
|
551
|
+
// Files to scan for class names
|
|
552
|
+
content: [
|
|
553
|
+
'./src/**/*.{html,jsx,tsx,vue,astro,svelte}'
|
|
554
|
+
],
|
|
555
|
+
|
|
556
|
+
// Input and output paths
|
|
557
|
+
input: './strata.css',
|
|
558
|
+
output: './dist/strata.output.css',
|
|
559
|
+
|
|
560
|
+
// Theme overrides
|
|
561
|
+
theme: {
|
|
562
|
+
breakpoints: {
|
|
563
|
+
'3xl': '1600px' // add custom breakpoints
|
|
564
|
+
},
|
|
565
|
+
colors: {
|
|
566
|
+
primary: '#7c3aed' // override default colors
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
|
|
570
|
+
// Include or exclude specific components
|
|
571
|
+
components: {
|
|
572
|
+
exclude: ['carousel']
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## Breakpoints
|
|
580
|
+
|
|
581
|
+
Bootstrap-style — breakpoint embedded inside the class name.
|
|
582
|
+
|
|
583
|
+
| Breakpoint | Prefix | Min-width |
|
|
584
|
+
|---|---|---|
|
|
585
|
+
| Extra small | `xs` | 0px |
|
|
586
|
+
| Small | `sm` | 576px |
|
|
587
|
+
| Medium | `md` | 768px |
|
|
588
|
+
| Large | `lg` | 992px |
|
|
589
|
+
| Extra large | `xl` | 1200px |
|
|
590
|
+
| Extra extra large | `xxl` | 1400px |
|
|
591
|
+
|
|
592
|
+
```html
|
|
593
|
+
<div class="col-12 col-md-6 col-lg-4">
|
|
594
|
+
<div class="d-none d-md-block">
|
|
595
|
+
<div class="mt-2 mt-md-4 mt-lg-5">
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## CSS Variables Reference
|
|
601
|
+
|
|
602
|
+
| Variable | Default | Purpose |
|
|
603
|
+
|---|---|---|
|
|
604
|
+
| `--st-primary` | `#0d6efd` | Primary brand colour |
|
|
605
|
+
| `--st-secondary` | `#6c757d` | Secondary colour |
|
|
606
|
+
| `--st-success` | `#198754` | Success colour |
|
|
607
|
+
| `--st-danger` | `#dc3545` | Danger colour |
|
|
608
|
+
| `--st-warning` | `#ffc107` | Warning colour |
|
|
609
|
+
| `--st-info` | `#0dcaf0` | Info colour |
|
|
610
|
+
| `--st-bg` | `#ffffff` | Page background |
|
|
611
|
+
| `--st-text` | `#212529` | Body text |
|
|
612
|
+
| `--st-border` | `#dee2e6` | Border colour |
|
|
613
|
+
| `--st-border-radius` | `0.375rem` | Default radius |
|
|
614
|
+
| `--st-duration` | `200ms` | Transition duration |
|
|
615
|
+
| `--st-easing` | `cubic-bezier(0.4,0,0.2,1)` | Transition easing |
|
|
616
|
+
| `--st-shadow` | `0 0.5rem 1rem rgba(0,0,0,0.15)` | Default shadow |
|
|
617
|
+
| `--st-font-family` | System font stack | Body font |
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## Framework Compatibility
|
|
622
|
+
|
|
623
|
+
Strata works with any project that can consume a CSS file.
|
|
624
|
+
|
|
625
|
+
| Framework | Supported |
|
|
626
|
+
|---|---|
|
|
627
|
+
| Plain HTML | ✓ |
|
|
628
|
+
| React / Next.js | ✓ |
|
|
629
|
+
| Vue / Nuxt | ✓ |
|
|
630
|
+
| Astro | ✓ |
|
|
631
|
+
| Svelte / SvelteKit | ✓ |
|
|
632
|
+
| Angular | ✓ |
|
|
633
|
+
| PHP / Laravel | ✓ |
|
|
634
|
+
| Django / Rails | ✓ |
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## Build Tool Integration
|
|
639
|
+
|
|
640
|
+
### Vite
|
|
641
|
+
|
|
642
|
+
```js
|
|
643
|
+
// vite.config.js
|
|
644
|
+
import { defineConfig } from 'vite'
|
|
645
|
+
|
|
646
|
+
export default defineConfig({
|
|
647
|
+
css: {
|
|
648
|
+
postcss: {
|
|
649
|
+
plugins: [require('strata-css')]
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
})
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
### Webpack
|
|
656
|
+
|
|
657
|
+
```js
|
|
658
|
+
// webpack.config.js
|
|
659
|
+
module.exports = {
|
|
660
|
+
module: {
|
|
661
|
+
rules: [{
|
|
662
|
+
test: /\.css$/,
|
|
663
|
+
use: ['style-loader', 'css-loader', 'postcss-loader']
|
|
664
|
+
}]
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### PostCSS
|
|
670
|
+
|
|
671
|
+
```js
|
|
672
|
+
// postcss.config.js
|
|
673
|
+
module.exports = {
|
|
674
|
+
plugins: [
|
|
675
|
+
require('strata-css'),
|
|
676
|
+
require('autoprefixer')
|
|
677
|
+
]
|
|
678
|
+
}
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
---
|
|
682
|
+
|
|
683
|
+
## Roadmap
|
|
684
|
+
|
|
685
|
+
### v1.0 — Current
|
|
686
|
+
Full component library, utility system, JIT processing, three-theme system, transition system.
|
|
687
|
+
|
|
688
|
+
### v2.0 — Planned
|
|
689
|
+
- Formal plugin API
|
|
690
|
+
- VSCode IntelliSense extension
|
|
691
|
+
- Strata DevTools browser extension
|
|
692
|
+
- Design token pipeline (Figma support)
|
|
693
|
+
- Storybook integration
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
## Acknowledgements
|
|
698
|
+
|
|
699
|
+
Strata builds on the shoulders of excellent prior work:
|
|
700
|
+
|
|
701
|
+
- **[Bootstrap](https://getbootstrap.com/)** (MIT) — component class naming conventions, breakpoint scale, color palette, and form patterns that Strata's API is compatible with
|
|
702
|
+
- **[Tailwind CSS](https://tailwindcss.com/)** (MIT) — the JIT processing concept and arbitrary value syntax (`mt-[24px]`, `bg-[#ff0000]`)
|
|
703
|
+
- **[PostCSS](https://postcss.org/)** (MIT) — the build pipeline that powers Strata's `@strata` directive processing
|
|
704
|
+
|
|
705
|
+
Strata's component architecture, cascade layer system, `data-st-*` state model, theming engine, and JIT registry are original work.
|
|
706
|
+
|
|
707
|
+
---
|
|
708
|
+
|
|
709
|
+
## Creating a GitHub Release
|
|
710
|
+
|
|
711
|
+
The v1.0.0 tag already exists. To publish the GitHub Release from it:
|
|
712
|
+
|
|
713
|
+
```bash
|
|
714
|
+
gh release create v1.0.0 \
|
|
715
|
+
--title "Strata CSS v1.0.0" \
|
|
716
|
+
--notes-file CHANGELOG.md \
|
|
717
|
+
--verify-tag
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
722
|
+
## Contributing
|
|
723
|
+
|
|
724
|
+
Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting a pull request.
|
|
725
|
+
|
|
726
|
+
---
|
|
727
|
+
|
|
728
|
+
## License
|
|
729
|
+
|
|
730
|
+
[MIT](LICENSE) © 2026 Aftab Ibrahim Kazi
|