chaincss 2.3.1 → 2.3.2

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/README.md CHANGED
@@ -62,6 +62,242 @@ const hero = chain()
62
62
  **No CSS syntax. No template literals. Compiler-enforced quality.**
63
63
 
64
64
 
65
+ # Constraint-Based Styling
66
+
67
+ Declare relationships, not values. The constraint solver compiles them to native CSS at build time.
68
+
69
+ **No runtime JS. No manual `calc()`. The compiler picks the best CSS feature.**
70
+
71
+ ---
72
+
73
+ ## 1. Aspect Ratios from Math
74
+
75
+ Describe the relationship between width and height:
76
+
77
+ ```ts
78
+ chain()
79
+ .constrain("height", "= width * 0.5") // 2:1 ratio
80
+ .constrain("width", "< parent") // Don't overflow container
81
+ .$el("video");
82
+ ```
83
+
84
+ ### Compiles to
85
+
86
+ ```css
87
+ .video {
88
+ aspect-ratio: 1 / 2;
89
+ max-width: 100%;
90
+ }
91
+ ```
92
+
93
+ The solver detects `width * 0.5` and emits `aspect-ratio` instead of:
94
+
95
+ ```css
96
+ height: calc(width * 0.5);
97
+ ```
98
+
99
+ `aspect-ratio` has better performance and avoids layout shifts.
100
+
101
+ ### Tailwind Equivalent
102
+
103
+ ```txt
104
+ aspect-[2/1] max-w-full
105
+ ```
106
+
107
+ ### ChainCSS Difference
108
+
109
+ You write the math. The compiler writes the CSS.
110
+
111
+ ---
112
+
113
+ ## 2. Container-Aware Responsive Layouts
114
+
115
+ Use conditional constraints to generate `@container` queries automatically.
116
+
117
+ ```ts
118
+ chain()
119
+ .constrain("columns", ">= 3 when > 768px")
120
+ .constrain("gap", "= 24px")
121
+ .$el("grid");
122
+ ```
123
+
124
+ ### Compiles to
125
+
126
+ ```css
127
+ .grid {
128
+ gap: 24px;
129
+ }
130
+
131
+ @container (min-width: 768px) {
132
+ .grid {
133
+ columns: 3;
134
+ }
135
+ }
136
+ ```
137
+
138
+ > Requires `container-type: inline-size` on the parent.
139
+ > ChainCSS adds it automatically when container constraints are detected.
140
+
141
+ ---
142
+
143
+ ## 3. Fluid Values with `clamp()`
144
+
145
+ Stop calculating `clamp()` manually.
146
+
147
+ ```ts
148
+ chain()
149
+ .constrain("fontSize", "= clamp(14px, 5vw, 24px)")
150
+ .constrain("padding", "= clamp(16px, 4vw, 32px)")
151
+ .$el("hero");
152
+ ```
153
+
154
+ ### Compiles to
155
+
156
+ ```css
157
+ .hero {
158
+ font-size: clamp(14px, 5vw, 24px);
159
+ padding: clamp(16px, 4vw, 32px);
160
+ }
161
+ ```
162
+
163
+ Works with:
164
+
165
+ - `clamp()`
166
+ - `min()`
167
+ - `max()`
168
+ - `calc()`
169
+
170
+ ---
171
+
172
+ ## 4. Scroll-Driven Sticky Positioning
173
+
174
+ "Stick this element until another element reaches the viewport."
175
+
176
+ ```ts
177
+ chain()
178
+ .constrain("sidebar", "sticky until footer")
179
+ .$el("sidebar");
180
+ ```
181
+
182
+ ### Compiles to
183
+
184
+ ```css
185
+ .sidebar {
186
+ position: sticky;
187
+ top: 0;
188
+
189
+ animation: sticky-sidebar 1s linear both;
190
+ animation-timeline: scroll();
191
+ animation-range: contain 0% contain 100%;
192
+ }
193
+
194
+ @keyframes sticky-sidebar {
195
+ to {
196
+ position: relative;
197
+ }
198
+ }
199
+ ```
200
+
201
+ Zero JavaScript. Uses native `animation-timeline: scroll()` available in modern Chromium browsers.
202
+
203
+ ---
204
+
205
+ ## 5. Parent-Relative Constraints
206
+
207
+ Keep elements inside their parents without writing media queries.
208
+
209
+ ```ts
210
+ chain()
211
+ .constrain("width", "< parent")
212
+ .constrain("width", "> 320px")
213
+ .$el("modal");
214
+ ```
215
+
216
+ ### Compiles to
217
+
218
+ ```css
219
+ .modal {
220
+ max-width: 100%;
221
+ min-width: 320px;
222
+ }
223
+ ```
224
+
225
+ ---
226
+
227
+ # How It Works
228
+
229
+ The compiler parses constraint expressions and resolves them into the most optimal native CSS feature.
230
+
231
+ | You Write | Compiler Resolves To | Strategy |
232
+ |---|---|---|
233
+ | `width < parent` | `max-width: 100%` | Direct mapping |
234
+ | `height = width * 0.5` | `aspect-ratio: 1 / 2` | Aspect-ratio optimization |
235
+ | `fontSize = clamp(14, 5vw, 24)` | `font-size: clamp(...)` | Native clamp |
236
+ | `columns >= 3 when > 768px` | `@container (min-width: 768px)` | Container query |
237
+ | `sidebar sticky until footer` | `animation-timeline: scroll()` | Scroll timeline |
238
+
239
+ ---
240
+
241
+ ## Supported Operators
242
+
243
+ ```txt
244
+ < > <= >= = !=
245
+ ```
246
+
247
+ ## Supported References
248
+
249
+ ```txt
250
+ parent
251
+ viewport
252
+ self
253
+ sibling.width
254
+ ```
255
+
256
+ ## Supported Functions
257
+
258
+ ```txt
259
+ clamp()
260
+ min()
261
+ max()
262
+ calc()
263
+ ```
264
+
265
+ ---
266
+
267
+ # Debugging Constraints
268
+
269
+ See how constraints were resolved during compilation.
270
+
271
+ ## CLI
272
+
273
+ ```bash
274
+ chaincss build --explain
275
+ ```
276
+
277
+ ### Output
278
+
279
+ ```txt
280
+ card: height = width * 0.5 → aspect-ratio: 1/2
281
+ card: width < parent → max-width: 100%
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Programmatic Debugging
287
+
288
+ ```ts
289
+ import { resolveConstraint } from "chaincss/compiler";
290
+
291
+ const result = resolveConstraint({
292
+ property: "height",
293
+ operator: "=",
294
+ expression: "width * 0.5",
295
+ });
296
+
297
+ console.log(result.explanation);
298
+ // "height = width * 0.5 → aspect-ratio: 1/2"
299
+ ```
300
+
65
301
 
66
302
  # What Makes ChainCSS Different
67
303