···
+
Type-safe Tailwind CSS generation for OCaml with a revolutionary GADT-based interface for succinct, compile-time validated styling.
This project provides two main libraries:
- **`tailwind`**: Core library for type-safe Tailwind CSS class generation
+
- **`tailwind-html`**: High-level HTML component library with GADT-based heterogeneous list interface built on [Htmlit](https://github.com/dbuenzli/htmlit)
+
- **GADT-based Interface**: Succinct heterogeneous list syntax with compile-time type safety
+
- **Zero Runtime Cost**: All CSS generation happens at compile time
+
- **Comprehensive Grid Support**: Full CSS Grid integration with type-safe properties
+
- **Type-Safe Colors & Spacing**: Exhaustive variants with compile-time validation
+
- **Built-in Components**: Pre-styled buttons, cards, and layout helpers
+
### Complete Tailwind Coverage
+
- **Typography**: Font sizes, weights, text alignment with type-safe variants
+
- **Layout**: CSS Grid, Flexbox, spacing with compile-time validation
+
- **Colors**: Full palette (gray, blue, red, green, etc.) with variant checking
- **Effects**: Shadows, borders, rounded corners, transitions
+
- **Components**: Pre-built buttons, cards, and layout helpers
+
- **Type Safety**: GADT-based heterogeneous lists prevent invalid combinations
+
### GADT Interface (Recommended)
+
The new GADT-based interface provides succinct, type-safe styling with heterogeneous lists:
+
(* Create a centered card with CSS Grid *)
+
let create_hero_section () =
+
margin_bottom (rem 1.5);
+
] [txt "Welcome to Tailwind OCaml"];
+
margin_bottom (rem 2.0);
+
] [txt "Type-safe CSS with compile-time guarantees"];
+
(* Built-in button components *)
+
btn_primary ~size:`Lg [txt "Get Started"];
+
(* Three-column responsive grid *)
+
card [h3 [txt "Feature 1"]; p [txt "Description"]];
+
card [h3 [txt "Feature 2"]; p [txt "Description"]];
+
card [h3 [txt "Feature 3"]; p [txt "Description"]];
+
### Built-in Components
+
(* Pre-styled components with size variants *)
+
btn_primary ~size:`Lg [txt "Primary Action"];
+
btn_secondary [txt "Secondary Action"];
+
btn_outline ~size:`Sm [txt "Outline Button"];
+
h2 ~styles:[font_size `Xl; margin_bottom (rem 1.0)] [txt "Card Title"];
+
p ~styles:[text_color (gray 600)] [txt "Card content with automatic styling"];
+
The `examples/` directory showcases the GADT interface across various use cases:
+
# Hello World with GADT interface
+
dune exec examples/hello_tailwind_01.exe > hello.html
+
# Colors and Typography showcase
+
dune exec examples/colors_and_typography_02.exe > colors.html
+
# CSS Grid and Layout demonstrations
+
dune exec examples/layout_and_spacing_03.exe > layout.html
+
# Responsive design patterns
+
dune exec examples/responsive_design_04.exe > responsive.html
+
# Visual effects and styling
+
dune exec examples/effects_and_variants_05.exe > effects.html
+
# Component patterns and reusable elements
+
dune exec examples/patterns_and_components_06.exe > patterns.html
+
# Complete application showcase
+
dune exec examples/comprehensive_showcase_07.exe > showcase.html
+
# Button component demonstration
+
dune exec examples/button_demo.exe > buttons.html
+
# Generate index page linking all examples
+
dune exec examples/index_html_generator.exe > index.html
+
**CSS Grid Layout (`layout_and_spacing_03.ml`)**:
+
(* Three-column grid with gap variations *)
+
div ~styles:[bg_color (blue 100); padding (rem 1.0)] [txt "Item 1"];
+
div ~styles:[bg_color (green 100); padding (rem 1.0)] [txt "Item 2"];
+
div ~styles:[bg_color (purple 100); padding (rem 1.0)] [txt "Item 3"];
+
(* Asymmetric grid gaps *)
+
] (List.init 4 (fun i ->
+
div ~styles:[bg_color (purple 200); text_center] [
+
txt (Printf.sprintf "Box %d" (i + 1))
+
**Built-in Components (`button_demo.ml`)**:
+
(* Size variants with consistent styling *)
+
div ~styles:[flex; flex_col; gap (rem 1.0)] [
+
btn_primary ~size:`Sm [txt "Small Primary"];
+
btn_primary [txt "Default Primary"];
+
btn_primary ~size:`Lg [txt "Large Primary"];
+
btn_secondary [txt "Secondary Button"];
+
btn_outline [txt "Outline Button"];
+
**Responsive Cards (`comprehensive_showcase_07.ml`)**:
+
section ~styles:[margin_bottom (rem 4.0)] [
+
h3 ~styles:[font_size `Xl2; text_center; margin_bottom (rem 3.0)] [
+
div ~styles:[grid; grid_cols 1; gap (rem 2.0)] [
+
h4 ~styles:[font_size `Xl; font_weight `Semibold; text_color (blue 600)] [
+
p ~styles:[text_color (gray 600)] [
+
txt "Catch styling errors at compile time with GADT-based type checking."
+
h4 ~styles:[font_size `Xl; font_weight `Semibold; text_color (green 600)] [
+
p ~styles:[text_color (gray 600)] [
+
txt "Zero runtime overhead with compile-time CSS generation."
···
npx tailwindcss@next -i input.css -o output.css
+
### `Tailwind_html` (GADT Interface)
+
The high-level GADT interface provides succinct, type-safe styling with heterogeneous lists:
+
grid | flex | block | inline | hidden;
+
grid_cols 3 | grid_rows 2;
+
gap (rem 1.0) | gap_x (rem 1.5) | gap_y (rem 0.5);
+
justify_center | justify_between | justify_end;
+
items_center | items_start | items_end;
+
width full | height screen;
+
min_height screen | max_width (rem 64.0);
+
#### Typography Properties
+
font_size `Xs | font_size `Sm | font_size `Base | font_size `Lg;
+
font_size `Xl | font_size `Xl2 | font_size `Xl3;
+
font_weight `Light | font_weight `Normal | font_weight `Medium;
+
font_weight `Semibold | font_weight `Bold;
+
text_center | text_left | text_right;
+
text_color (blue 600) | text_color (gray 500);
+
(* Background Colors *)
+
bg_color (blue 50) | bg_color (gray 100) | bg_color (red 500);
+
bg_color (Tailwind.Color.white) | bg_color (green 600);
+
text_color (gray 800) | text_color (blue 600) | text_color (red 500);
+
border_color (gray 200) | border_color (blue 300);
+
#### Spacing Properties
+
padding (rem 1.0) | padding_x (rem 1.5) | padding_y (rem 2.0);
+
margin (rem 1.0) | margin_x auto | margin_bottom (rem 2.0);
+
margin_top (rem 1.5) | margin_left (rem 0.5);
+
shadow `Sm | shadow `Md | shadow `Lg | shadow `Xl;
+
border | rounded `Sm | rounded `Md | rounded `Lg | rounded `Full;
+
#### Built-in Components
+
(* Button Components *)
+
btn_primary ~size:`Lg [txt "Primary Button"];
+
btn_secondary ~size:`Sm [txt "Secondary Button"];
+
btn_outline [txt "Outline Button"];
+
(* Layout Components *)
+
container [content]; (* Max-width container with auto margins *)
+
card [content]; (* Pre-styled card with padding and shadow *)
+
(* HTML Elements with Styling *)
+
h1 ~styles:[font_size `Xl3; font_weight `Bold] [txt "Heading"];
+
p ~styles:[text_color (gray 600); margin_bottom (rem 1.0)] [txt "Paragraph"];
+
div ~styles:[grid; grid_cols 2; gap (rem 1.0)] [content];
+
section ~styles:[margin_bottom (rem 2.0)] [content];
+
### Low-Level `Tailwind` Module
+
For advanced use cases, the core `Tailwind` module provides detailed control:
+
Grid.(to_class (template_cols (`Cols 3)));
+
Spacing.(to_class (gap `All (Size.rem 1.0)));
+
Color.bg (Color.make `Blue ~variant:`V50 ());
+
let html_class = to_string classes (* "grid grid-cols-3 gap-4 bg-blue-50" *)
+
Add to your `dune-project`:
+
Then in your OCaml code:
+
let my_page = El.html [
+
El.head [El.title [txt "My App"]];
+
El.body ~at:[classes_attr [min_height screen; bg_color (gray 50)]] [
+
h1 ~styles:[font_size `Xl3; text_center; margin_bottom (rem 2.0)] [
+
txt "Welcome to Type-Safe CSS!"
+
btn_primary [txt "Get Started"];