Compositor is a system of constraints designed to produce aesthetically pleasing, typographic compositions, based on objective, constant dimensions of space.
A baseline-grid typography system for tailwindcss.
Algorithm Demo: Styled Baseline
You will need fontkit, postcss and tailwindcss installed along with the plugin
npm install postcss fontkit tailwindcss tailwind-compositor
In your postcss.config.js
you will need to import your standard tailwind.config.js
, but also your compositor.config.js
.
The { compositor }
will receive both, merge with your tailwind config, and return a standard tailwind configuration.
const tailwindcss = require('tailwindcss');
const { compositor } = require('tailwind-compositor');
// import both configurations
const compositorConfig = require('./compositor.config.js');
const tailwindConfig = require('./tailwind.config.js');
// compose config
const tailwindConfigComposed = compositor(compositorConfig)(tailwindConfig);
// use with tailwind
module.exports = {
plugins: [
tailwindcss(tailwindConfigComposed),
],
};
module.exports = {
// root unit
root: 16,
// baseline grid height in px units
baseline: 8,
// maximum leading
leading: 4,
// matrix max columns
matrix: 4,
// type scale in px units
type: [16, 18, 20, 22, 24, 28, 30, 32, 40, 48, 56, 60, 72],
// spacing scale in baseline units
rhythm: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12],
// line width in ch units
measure: [10, 15, 20, 30, 35, 50, 55, 60, 65],
// webfonts and vertical metrics
fonts: [
{
key: "sans-400",
familyName: "Inter",
fallback: "sans-serif",
weight: 400,
italic: false,
upm: 2816,
xHeight: 1536,
capHeight: 2048,
ascent: 2728,
descent: -680
},
{
key: 'sans-600',
familyName: "Inter",
fallback: 'sans-serif',
file: path.resolve('./fonts/inter/Inter-Semibold.woff2'),
},
],
// compositor options
options: {
useRem: true,
snap: true,
type: true,
rhythm: true,
measure: true,
matrix: true,
xray: true,
},
}
The root font size, in px
units.
The baseline grid row height, in px
units.
The maximum leading value in baseline units.
The maximum columns on the matrix utility
type: [16, 18, 20, 22, 24, 28, 30, 32, 40, 48, 56, 60, 72]
The system's typographic scale, in px
units.
rhythm: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12]
The system's size and spacing scale, in baseline
units, used for rhythm
, margin
, padding
, width/min/max
, height/min/max
and grid-gap
utilities
measure: [10, 15, 20, 30, 35, 50, 55, 60, 65]
Separate scale used for measure
(line-width) utilities, configured in ch
units.
The font scale provides all the information needed to render text styles. Each entry describes a font/weight/style set, and only those that are part of the system will be enabled.
The file
property, is used to extract the vertical metrics dynamically from the font-file. If you want to configure the metrics manually, you can omit the file
prop.
The key
property is used to name the utility classes. The configuration bellow will produce four font styles. The recommended convention is ${family}-${weight}${style}
.
font-sans-400
: Inter Regularfont-sans-400i
: Inter Regular Italicfont-sans-600i
: Inter Semiboldfont-sans-600i
: Inter Semibold Italic
{
key: "sans-400",
familyName: "Inter",
fallback: "sans-serif",
weight: 400,
italic: false,
upm: 2816,
xHeight: 1536,
capHeight: 2048,
lineGap: 0,
ascent: 2728,
descent: -680
},
{
key: 'sans-400i',
familyName: "Inter",
fallback: 'sans-serif',
file: path.resolve('./fonts/inter/Inter-Italic.woff2'),
},
{
key: 'sans-600',
familyName: "Inter",
fallback: 'sans-serif',
file: path.resolve('./fonts/inter/Inter-Semibold.woff2'),
},
{
key: 'sans-600i',
familyName: "Inter",
fallback: 'sans-serif',
file: path.resolve('./fonts/inter/Inter-SemiboldItalic.woff2'),
},
Options properties, are used to enable/disable individual compositor utilities.
If useRem
is set to true, compositor will use the root unit value, to transform all spacing and font-size utilities, to relative units. Line-height will be transformed to unitless ratios.
If snap
is true, compositor will align each line text to the nearest baseline grid row, otherwise will trim the line-height above the capHeight and below the baseline, and apply a constant lineGap between lines of text.
useRem: boolean
transform to relative unitssnap: boolean
Align text styles to a baseline gridtype: boolean
Enable typographic utilitiesrhythm: boolean
Enable rhythm utilitiesmeasure: boolean
Enable measure utilitiesmatrix: boolean
Enable matrix utilitiesxray: boolean
Enable debug utilities
options: {
useRem: true,
snap: true,
type: true,
rhythm: true,
measure: true,
matrix: true,
xray: true,
}
- font:
font-{font-key}
// fonts: [
// { key: "sans-400", ... },
// { key: 'sans-400i', ... },
// { key: 'sans-600', ... },
// { key: 'sans-600i', ... },
// ],
// sans semibold italic
<h3 class="font-sans-600i" />
// sans regular
<p class="font-sans-400" />
// sans regular italic
<p class="font-sans-400i" />
- Text Style :
text-{type_scale_index}/{leading_baseline_units}
// type: [16, 18, 20, 22, 24, 28, 30, 32, 40, 48, 56]
// sans semibold italic - 56px / leading 3
<h3 class="font-sans-600i text-10/3" />
// sans regular - 20px / leading 3
<p class="font-sans-400 text-2/3" />
// sans regular italic - 18px / leading 2
<p class="font-sans-400i text-1/2" />
measure-{measure_scale_index}
// measure: [10, 15, 20, 30, 35, 50, 55, 60, 65]
// 10ch
<p class="measure-0">Ad proident quis enim duis commodo.</p>
// 15ch
<p class="measure-1">Ad proident quis enim duis commodo.</p>
// 20ch
<p class="measure-2">Ad proident quis enim duis commodo.</p>
// 30ch
<p class="measure-3">Ad proident quis enim duis commodo.</p>
When the tailwind theme is composed, the rhythm scale is transformed to tailwindcss spacing scale and can be used for all spacing utilities, margin, padding and grid-gap.
- Margin:
m-{rhythm_scale_index}
- Margin Left:
ml-{rhythm_scale_index}
- Padding:
p-{rhythm_scale_index}
- ...etc
// rhythm: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12]
<section class="px-4 py-5">
<h3 class="sans400 text-7/3 mb-4" />
<input type="text" class="h-8 mb-4" />
<p class="sans400i text-1/2" />
</section>
Compositor also applies the spacing scale to tailwind sizing scales, width, min/max width and also height min/max.
- Height:
h-{rhythm_scale_index}
- Min Height:
min-h-{rhythm_scale_index}
- Max Height:
max-h-{rhythm_scale_index}
- ...etc
<section class="min-h-10 flex flex-col items-end">
<button class="h-8" />
</section>
- Vertical rhythm (alias):
rhythm-{rhythm_scale_index}
- Vertical rhythm:
rhythm-y-{rhythm_scale_index}
- Horizontal Rhythm:
rhythm-x-{rhythm_scale_index}
<section class="rhythm-3 lg:rhythm-5" />
<h3 class="sans400 text-7/3" />
<p class="sans400 text-5/3" />
// render horizontally
<div class="flex flex-row rhythm-x-2" >
<button />
<button />
</div>
</section>
- Matrix:
matrix-{columns_length}
- Matrix Gap:
matrix-gap-{rhythm_scale_index}
- Matrix Gap X:
matrix-gap-x-{rhythm_scale_index}
- Matrix Gap Y:
matrix-gap-y-{rhythm_scale_index}
By default every child of the matrix, will be placed in the next available column and will span for 1 column. In many cases you might not need any cell utilities or only the cell-span-x
utility.
- Cell Start X:
cell-start-x-{columns_index}
- Cell Span X:
cell-span-x-{columns_index}
- Background grid lines:
bg-baseline
<section class="bg-baseline" />