Tailwind classes in OCaml
1# Tailwind OCaml
2
3Type-safe Tailwind CSS generation for OCaml with a revolutionary GADT-based interface for succinct, compile-time validated styling.
4
5This project provides two main libraries:
6
7- **`tailwind`**: Core library for type-safe Tailwind CSS class generation
8- **`tailwind-html`**: High-level HTML component library with GADT-based heterogeneous list interface built on [Htmlit](https://github.com/dbuenzli/htmlit)
9
10## Features
11
12- **GADT-based Interface**: Succinct heterogeneous list syntax with compile-time type safety
13- **Zero Runtime Cost**: All CSS generation happens at compile time
14- **Comprehensive Grid Support**: Full CSS Grid integration with type-safe properties
15- **Type-Safe Colors & Spacing**: Exhaustive variants with compile-time validation
16- **Built-in Components**: Pre-styled buttons, cards, and layout helpers
17
18### Complete Tailwind Coverage
19- **Typography**: Font sizes, weights, text alignment with type-safe variants
20- **Layout**: CSS Grid, Flexbox, spacing with compile-time validation
21- **Colors**: Full palette (gray, blue, red, green, etc.) with variant checking
22- **Effects**: Shadows, borders, rounded corners, transitions
23- **Components**: Pre-built buttons, cards, and layout helpers
24- **Type Safety**: GADT-based heterogeneous lists prevent invalid combinations
25
26## Quick Start
27
28### GADT Interface (Recommended)
29
30The new GADT-based interface provides succinct, type-safe styling with heterogeneous lists:
31
32```ocaml
33open Htmlit
34open Tailwind_html
35
36(* Create a centered card with CSS Grid *)
37let create_hero_section () =
38 div ~styles:[
39 grid;
40 grid_cols 1;
41 gap (rem 2.0);
42 padding (rem 3.0);
43 text_center;
44 ] [
45 h1 ~styles:[
46 font_size `Xl3;
47 font_weight `Bold;
48 text_color (blue 600);
49 margin_bottom (rem 1.5);
50 ] [txt "Welcome to Tailwind OCaml"];
51
52 p ~styles:[
53 font_size `Lg;
54 text_color (gray 600);
55 margin_bottom (rem 2.0);
56 ] [txt "Type-safe CSS with compile-time guarantees"];
57
58 (* Built-in button components *)
59 btn_primary ~size:`Lg [txt "Get Started"];
60 ]
61```
62
63### CSS Grid Layouts
64
65```ocaml
66(* Three-column responsive grid *)
67div ~styles:[
68 grid;
69 grid_cols 3;
70 gap (rem 1.5);
71] [
72 card [h3 [txt "Feature 1"]; p [txt "Description"]];
73 card [h3 [txt "Feature 2"]; p [txt "Description"]];
74 card [h3 [txt "Feature 3"]; p [txt "Description"]];
75]
76```
77
78### Built-in Components
79
80```ocaml
81(* Pre-styled components with size variants *)
82btn_primary ~size:`Lg [txt "Primary Action"];
83btn_secondary [txt "Secondary Action"];
84btn_outline ~size:`Sm [txt "Outline Button"];
85
86(* Layout helpers *)
87container [
88 card [
89 h2 ~styles:[font_size `Xl; margin_bottom (rem 1.0)] [txt "Card Title"];
90 p ~styles:[text_color (gray 600)] [txt "Card content with automatic styling"];
91 ];
92]
93```
94
95## Examples
96
97The `examples/` directory showcases the GADT interface across various use cases:
98
99### Available Examples
100
101```bash
102# Build all examples
103dune build examples/
104
105# Hello World with GADT interface
106dune exec examples/hello_tailwind_01.exe > hello.html
107
108# Colors and Typography showcase
109dune exec examples/colors_and_typography_02.exe > colors.html
110
111# CSS Grid and Layout demonstrations
112dune exec examples/layout_and_spacing_03.exe > layout.html
113
114# Responsive design patterns
115dune exec examples/responsive_design_04.exe > responsive.html
116
117# Visual effects and styling
118dune exec examples/effects_and_variants_05.exe > effects.html
119
120# Component patterns and reusable elements
121dune exec examples/patterns_and_components_06.exe > patterns.html
122
123# Complete application showcase
124dune exec examples/comprehensive_showcase_07.exe > showcase.html
125
126# Button component demonstration
127dune exec examples/button_demo.exe > buttons.html
128
129# Generate index page linking all examples
130dune exec examples/index_html_generator.exe > index.html
131```
132
133### Example Highlights
134
135**CSS Grid Layout (`layout_and_spacing_03.ml`)**:
136```ocaml
137(* Three-column grid with gap variations *)
138div ~styles:[
139 grid;
140 grid_cols 3;
141 gap (rem 1.0);
142] [
143 div ~styles:[bg_color (blue 100); padding (rem 1.0)] [txt "Item 1"];
144 div ~styles:[bg_color (green 100); padding (rem 1.0)] [txt "Item 2"];
145 div ~styles:[bg_color (purple 100); padding (rem 1.0)] [txt "Item 3"];
146]
147
148(* Asymmetric grid gaps *)
149div ~styles:[
150 grid;
151 grid_cols 2;
152 gap_x (rem 2.0);
153 gap_y (rem 0.5);
154] (List.init 4 (fun i ->
155 div ~styles:[bg_color (purple 200); text_center] [
156 txt (Printf.sprintf "Box %d" (i + 1))
157 ]
158))
159```
160
161**Built-in Components (`button_demo.ml`)**:
162```ocaml
163(* Size variants with consistent styling *)
164div ~styles:[flex; flex_col; gap (rem 1.0)] [
165 btn_primary ~size:`Sm [txt "Small Primary"];
166 btn_primary [txt "Default Primary"];
167 btn_primary ~size:`Lg [txt "Large Primary"];
168 btn_secondary [txt "Secondary Button"];
169 btn_outline [txt "Outline Button"];
170]
171```
172
173**Responsive Cards (`comprehensive_showcase_07.ml`)**:
174```ocaml
175section ~styles:[margin_bottom (rem 4.0)] [
176 h3 ~styles:[font_size `Xl2; text_center; margin_bottom (rem 3.0)] [
177 txt "Features"
178 ];
179
180 div ~styles:[grid; grid_cols 1; gap (rem 2.0)] [
181 card [
182 h4 ~styles:[font_size `Xl; font_weight `Semibold; text_color (blue 600)] [
183 txt "🎯 Type Safety"
184 ];
185 p ~styles:[text_color (gray 600)] [
186 txt "Catch styling errors at compile time with GADT-based type checking."
187 ];
188 ];
189 card [
190 h4 ~styles:[font_size `Xl; font_weight `Semibold; text_color (green 600)] [
191 txt "⚡ Performance"
192 ];
193 p ~styles:[text_color (gray 600)] [
194 txt "Zero runtime overhead with compile-time CSS generation."
195 ];
196 ];
197 ];
198]
199```
200
201## Tailwind v4 Support
202
203This library supports Tailwind v4's CSS-first approach:
204
205```css
206/* Generated input.css - no config file needed! */
207@import "tailwindcss";
208
209@theme {
210 --font-sans: 'Inter', system-ui, sans-serif;
211 --color-brand-600: #2563eb;
212 /* Custom theme extensions */
213}
214```
215
216To process the CSS:
217```bash
218npx tailwindcss@next -i input.css -o output.css
219```
220
221## API Reference
222
223### `Tailwind_html` (GADT Interface)
224
225The high-level GADT interface provides succinct, type-safe styling with heterogeneous lists:
226
227#### Layout Properties
228```ocaml
229~styles:[
230 (* Display *)
231 grid | flex | block | inline | hidden;
232
233 (* Grid System *)
234 grid_cols 3 | grid_rows 2;
235 gap (rem 1.0) | gap_x (rem 1.5) | gap_y (rem 0.5);
236
237 (* Flexbox *)
238 flex_col | flex_row;
239 justify_center | justify_between | justify_end;
240 items_center | items_start | items_end;
241
242 (* Sizing *)
243 width full | height screen;
244 min_height screen | max_width (rem 64.0);
245]
246```
247
248#### Typography Properties
249```ocaml
250~styles:[
251 (* Font Sizes *)
252 font_size `Xs | font_size `Sm | font_size `Base | font_size `Lg;
253 font_size `Xl | font_size `Xl2 | font_size `Xl3;
254
255 (* Font Weights *)
256 font_weight `Light | font_weight `Normal | font_weight `Medium;
257 font_weight `Semibold | font_weight `Bold;
258
259 (* Text Styling *)
260 text_center | text_left | text_right;
261 text_color (blue 600) | text_color (gray 500);
262]
263```
264
265#### Color System
266```ocaml
267~styles:[
268 (* Background Colors *)
269 bg_color (blue 50) | bg_color (gray 100) | bg_color (red 500);
270 bg_color (Tailwind.Color.white) | bg_color (green 600);
271
272 (* Text Colors *)
273 text_color (gray 800) | text_color (blue 600) | text_color (red 500);
274
275 (* Border Colors *)
276 border_color (gray 200) | border_color (blue 300);
277]
278```
279
280#### Spacing Properties
281```ocaml
282~styles:[
283 (* Padding *)
284 padding (rem 1.0) | padding_x (rem 1.5) | padding_y (rem 2.0);
285
286 (* Margin *)
287 margin (rem 1.0) | margin_x auto | margin_bottom (rem 2.0);
288 margin_top (rem 1.5) | margin_left (rem 0.5);
289]
290```
291
292#### Visual Effects
293```ocaml
294~styles:[
295 (* Shadows *)
296 shadow `Sm | shadow `Md | shadow `Lg | shadow `Xl;
297
298 (* Borders *)
299 border | rounded `Sm | rounded `Md | rounded `Lg | rounded `Full;
300
301 (* Transitions *)
302 transition;
303]
304```
305
306#### Built-in Components
307```ocaml
308(* Button Components *)
309btn_primary ~size:`Lg [txt "Primary Button"];
310btn_secondary ~size:`Sm [txt "Secondary Button"];
311btn_outline [txt "Outline Button"];
312
313(* Layout Components *)
314container [content]; (* Max-width container with auto margins *)
315card [content]; (* Pre-styled card with padding and shadow *)
316
317(* HTML Elements with Styling *)
318h1 ~styles:[font_size `Xl3; font_weight `Bold] [txt "Heading"];
319p ~styles:[text_color (gray 600); margin_bottom (rem 1.0)] [txt "Paragraph"];
320div ~styles:[grid; grid_cols 2; gap (rem 1.0)] [content];
321section ~styles:[margin_bottom (rem 2.0)] [content];
322```
323
324### Low-Level `Tailwind` Module
325
326For advanced use cases, the core `Tailwind` module provides detailed control:
327
328```ocaml
329open Tailwind
330
331let classes = Css.tw [
332 Display.grid;
333 Grid.(to_class (template_cols (`Cols 3)));
334 Spacing.(to_class (gap `All (Size.rem 1.0)));
335 Color.bg (Color.make `Blue ~variant:`V50 ());
336]
337
338let html_class = to_string classes (* "grid grid-cols-3 gap-4 bg-blue-50" *)
339```
340
341### Getting Started
342
343Add to your `dune-project`:
344```dune
345(package
346 (name myproject)
347 (depends
348 ocaml
349 dune
350 tailwind
351 tailwind-html
352 htmlit))
353```
354
355Then in your OCaml code:
356```ocaml
357open Htmlit
358open Tailwind_html
359
360let my_page = El.html [
361 El.head [El.title [txt "My App"]];
362 El.body ~at:[classes_attr [min_height screen; bg_color (gray 50)]] [
363 container [
364 h1 ~styles:[font_size `Xl3; text_center; margin_bottom (rem 2.0)] [
365 txt "Welcome to Type-Safe CSS!"
366 ];
367 btn_primary [txt "Get Started"];
368 ];
369 ];
370]
371```
372
373## Testing
374
375Run the test suite:
376
377```bash
378dune test
379```
380
381## Contributing
382
383Contributions are welcome! Please:
384
3851. Fork the repository
3862. Create a feature branch
3873. Make your changes with tests
3884. Submit a pull request
389
390## License
391
392MIT License - see LICENSE file for details
393
394## Acknowledgments
395
396- Built on top of [Htmlit](https://github.com/dbuenzli/htmlit) by Daniel Bünzli
397- Inspired by [Tailwind CSS](https://tailwindcss.com/)
398
399## Resources
400
401- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
402- [Tailwind v4 Alpha](https://tailwindcss.com/blog/tailwindcss-v4-alpha)
403- [Htmlit Documentation](https://erratique.ch/software/htmlit/doc/)