@formepdf/tailwind lets you style Forme components with Tailwind CSS utility classes instead of writing style objects by hand.
tw() function returns a plain FormeStyle object. You can spread it, merge it, or pass it directly to style.
How it works
tw() parses a space-separated string of Tailwind classes and returns the equivalent Forme style object. Unknown classes are silently ignored. When classes conflict, the last one wins.
Spacing
Tailwind spacing values are multiplied by 4 (matching Tailwind’s default 4px scale).p-4 = 16pt, m-2 = 8pt, etc.
| Class | Forme property |
|---|---|
p-{n} | padding |
px-{n} / py-{n} | paddingHorizontal / paddingVertical |
pt-{n} / pr-{n} / pb-{n} / pl-{n} | paddingTop / paddingRight / paddingBottom / paddingLeft |
m-{n} | margin |
mx-{n} / my-{n} | marginHorizontal / marginVertical |
mt-{n} / mr-{n} / mb-{n} / ml-{n} | marginTop / marginRight / marginBottom / marginLeft |
m-auto / mx-auto / my-auto | margin: "auto" / marginHorizontal: "auto" / marginVertical: "auto" |
p-px | padding: 1 |
Negative values
Prefix any spacing or positional class with- to negate:
Typography
| Class | Forme property |
|---|---|
text-xs / text-sm / text-base / text-lg / text-xl / text-2xl … text-9xl | fontSize (12, 14, 16, 18, 20, 24, 30, 36, 48, 60, 72, 96, 128) |
font-thin / font-light / font-normal / font-medium / font-semibold / font-bold / font-extrabold / font-black | fontWeight (100-900) |
italic | fontStyle: "italic" |
text-left / text-center / text-right / text-justify | textAlign |
leading-tight / leading-normal / leading-loose / leading-{n} | lineHeight |
tracking-tight / tracking-normal / tracking-wide | letterSpacing |
underline / line-through / no-underline | textDecoration |
uppercase / lowercase / capitalize / normal-case | textTransform |
Colors
The full Tailwind color palette is supported: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose. Each with shades 50-950.| Class | Forme property |
|---|---|
text-{color}-{shade} | color |
bg-{color}-{shade} | backgroundColor |
border-{color}-{shade} | borderColor |
text-black / text-white | color: "#000000" / color: "#ffffff" |
Layout
| Class | Forme property |
|---|---|
flex | No-op (flex is the default in Forme) |
flex-row / flex-col | flexDirection |
flex-row-reverse / flex-col-reverse | flexDirection |
items-start / items-center / items-end / items-stretch / items-baseline | alignItems |
justify-start / justify-center / justify-end / justify-between / justify-around / justify-evenly | justifyContent |
self-start / self-center / self-end / self-stretch / self-baseline | alignSelf |
flex-1 | flex: 1 |
flex-auto / flex-initial / flex-none | flex shortcuts |
flex-grow / flex-grow-0 | flexGrow |
flex-shrink / flex-shrink-0 | flexShrink |
flex-wrap / flex-nowrap | flexWrap |
gap-{n} / gap-x-{n} / gap-y-{n} | gap / columnGap / rowGap |
Dimensions
| Class | Forme property |
|---|---|
w-{n} / h-{n} | width / height (n * 4) |
w-full / h-full | width: "100%" / height: "100%" |
w-auto / h-auto | width: "auto" / height: "auto" |
w-1/2 / w-1/3 / w-2/3 / w-1/4 / w-3/4 | Percentage widths |
min-w-{n} / max-w-{n} | minWidth / maxWidth |
min-h-{n} / max-h-{n} | minHeight / maxHeight |
Fraction widths
Use fractions for percentage-based sizing:Grid
| Class | Forme property |
|---|---|
grid | display: "grid" |
grid-cols-{n} (1-12) | gridTemplateColumns: "repeat(n, 1fr)" |
grid-cols-none | gridTemplateColumns: "none" |
grid-rows-{n} (1-6) | gridTemplateRows: "repeat(n, 1fr)" |
grid-rows-none | gridTemplateRows: "none" |
col-span-{n} (1-12) | gridColumnSpan |
col-span-full | Span all columns |
col-start-{n} / col-end-{n} | gridColumnStart / gridColumnEnd |
row-span-{n} (1-6) | gridRowSpan |
row-span-full | Span all rows |
row-start-{n} / row-end-{n} | gridRowStart / gridRowEnd |
Borders
| Class | Forme property |
|---|---|
border | borderWidth: 1 |
border-0 / border-2 / border-4 / border-8 | borderWidth |
border-t / border-r / border-b / border-l | Per-side borderWidth: 1 |
border-t-{n} / border-r-{n} / border-b-{n} / border-l-{n} | Per-side borderWidth |
rounded / rounded-sm / rounded-md / rounded-lg / rounded-xl / rounded-2xl / rounded-3xl | borderRadius (4, 2, 6, 8, 12, 16, 24) |
rounded-full | borderRadius: 9999 |
rounded-none | borderRadius: 0 |
Positioning
| Class | Forme property |
|---|---|
relative / absolute | position |
top-{n} / right-{n} / bottom-{n} / left-{n} | Positional offsets (n * 4) |
overflow-hidden / overflow-visible | overflow |
Opacity
| Class | Forme property |
|---|---|
opacity-{0-100} | opacity (divided by 100) |
Arbitrary values
Use bracket syntax for exact values that don’t map to the Tailwind scale:px-[10], mt-[8], mx-[16], min-w-[100], max-h-[300], etc.
Real-world examples
Invoice header
Data grid
Badge
What’s not supported
These Tailwind features don’t apply to PDF rendering and are intentionally excluded:- Responsive prefixes (
sm:,md:,lg:) — PDFs have no viewport breakpoints - State variants (
hover:,focus:,active:) — PDFs are not interactive - Dark mode (
dark:) — no media queries in PDF space-x-{n}/space-y-{n}— these set margins on children, which requires more than a flat style objectz-index,aspect-ratio,object-fit— not supported by the Forme engine
TypeScript
tw() returns a FormeStyle type that’s compatible with Forme component style props: