Our general Tailwind setup involves a frontend.config.json
, tailwind.config.js
and an input.css
file.
We use values from this JSON file inside the Tailwind config to separate Tailwind config itself from front end site data. This JSON file is often read by a project's Webpack set up, a project's JavaScript and a project's CMS. This set up is, of course, not mandatory to use these plugins, but they may still prove inspiration for your Tailwind set up all the same.
This documentation site is made using Tailwind and AREA 17 tailwind plugins, this page documents the config files used for this site.
With the introduction of Tailwind 4, the setup of your project changes. Both use the same frontend.config.json
.
frontend.config.json
{
"structure": {
"breakpoints": {
"xs": "0",
"sm": "544px",
"md": "650px",
"lg": "990px",
"xl": "1300px",
"xxl": "1520px"
},
"columns": {
"xs": "4",
"sm": "4",
"md": "8",
"lg": "12",
"xl": "12",
"xxl": "12"
},
"container": {
"xs": "auto",
"sm": "auto",
"md": "auto",
"lg": "auto",
"xl": "auto",
"xxl": "1440px"
},
"gutters": {
"inner": {
"xs": "10px",
"sm": "15px",
"md": "20px",
"lg": "30px",
"xl": "40px",
"xxl": "40px"
},
"outer": {
"xs": "20px",
"sm": "30px",
"md": "40px",
"lg": "40px",
"xl": "40px",
"xxl": "0px"
}
}
},
"ratios": {
"1x1": "1:1",
"16x9": "16:9"
},
"spacing": {
"tokens": {
"scaler": 4,
"arbitraries": {
"400": "400px",
"600": "600px"
}
},
"groups": {
"outer-1": {
"xs": 64,
"lg": 96
},
"inner-1": {
"xs": 24,
"md": 40,
"lg": 64
},
"inner-2": {
"xs": 16,
"md": 24,
"lg": 32
}
}
},
"color": {
"tokens": {
"white": "#fff",
"grey-3": "#f8f8f8",
"grey-5": "#f2f2f2",
"grey-10": "#e6e6e6",
"grey-15": "#d9d9d9",
"grey-30": "#b3b3b3",
"grey-54": "#757575",
"grey-90": "#1a1a1a",
"black": "#000",
"blue-01": "#0A152B",
"blue-02": "#001F5C",
"blue-03": "#004F91",
"blue-04": "#313BFB",
"blue-05": "#81EEF3",
"blue-06": "#ADD8E6",
"red-01": "#f00"
},
"border": {
"primary": "grey-90",
"secondary": "grey-30",
"tertiary": "grey-54",
"quaternary": "blue-05",
"code-example-filename": "blue-05"
},
"text": {
"title": "black",
"primary": "grey-90",
"inverse": "white",
"secondary": "grey-54",
"accent": "blue-03",
"code": "black",
"code-example": "grey-3",
"code-example-filename": "blue-05",
"error": "red-01"
},
"background": {
"primary": "grey-10",
"header": "grey-10",
"container-demo": "white",
"footer": "grey-10",
"banner": "grey-90",
"accent": "blue-03",
"column": "blue-05",
"column-alt": "blue-04",
"code": "white",
"code-example": "grey-90",
"quote": "grey-5"
},
"underline": {
"primary": "grey-54",
"secondary": "blue-03"
},
"scrollbar": {
"track": {
"primary": "blue-06"
},
"thumb": {
"primary": "blue-03"
}
}
},
"typography": {
"families": {
"sans": "SuisseIntl, Helvetica, Arial, sans-serif",
"serif": "\"Times New Roman\", Georgia, serif",
"mono": "\"Lucida Console\", Courier, monospace"
},
"typesets": {
"h1": {
"xs": {
"font-family": "var(--font-sans)",
"font-weight": "500",
"bold-weight": "500",
"font-size": "32px",
"line-height": "1.2",
"letter-spacing": "-0.02em",
"font-smoothing": "true"
},
"md": {
"font-size": "36px"
},
"lg": {
"font-size": "48px"
}
},
"h2": {
"xs": {
"font-family": "var(--font-sans)",
"font-weight": "500",
"bold-weight": "500",
"font-size": "20px",
"line-height": "1.2",
"letter-spacing": "-0.02em",
"font-smoothing": "true"
},
"md": {
"font-size": "24px"
},
"lg": {
"font-size": "28px"
}
},
"h3": {
"xs": {
"font-family": "var(--font-sans)",
"bold-weight": "500",
"font-weight": "500",
"font-size": "16px",
"line-height": "1.2",
"letter-spacing": "-0.02em",
"font-smoothing": "true"
},
"md": {
"font-size": "20px"
}
},
"h4": {
"xs": {
"font-family": "var(--font-sans)",
"bold-weight": "600",
"font-weight": "600",
"font-size": "14px",
"line-height": "1.2",
"letter-spacing": "-0.02em",
"font-smoothing": "true"
},
"md": {
"font-size": "16px"
}
},
"body": {
"xs": {
"font-family": "var(--font-sans)",
"bold-weight": "600",
"font-size": "14px",
"line-height": "1.7",
"font-smoothing": "true"
},
"md": {
"font-size": "16px"
}
},
"ui": {
"xs": {
"font-family": "var(--font-sans)",
"font-size": "12px",
"line-height": 1.2,
"font-weight": 400
}
},
"code": {
"xs": {
"font-family": "var(--font-mono)",
"font-size": "14px",
"line-height": 1.2,
"font-weight": 400
}
}
}
}
}
-
structure
- here we describe the main layout of the site, its grid and composition, from these:root
variables will be madebreakpoints
- where each of our breakpoints starts-
columns
- how many design columns at each breakpoint -
container
- how wide the main container of the site is (auto
orpx/vw/rem
)
-
gutters
- gutters definitionsinner
- between design columnsouter
- on the outside of the main container
-
ratios
- which ratios should be generated for ratio boxes -
spacing
- define the spacing values for use in Tailwind spacing classes likeh-20
andmx-40
-
tokens
- people rarely think inrems
, they're abstract but as experienced screen developers we've been talking about pixels for years - we rename the spacing tokens to pixel values and use a function to convert them torems
and somt-16
will give you a margin top of16px
(which in the output CSS will be1rem
)
Note: not required for Tailwind 4 -
groups
- responsive spacing utility classes, create global spacing rules that are responsive and systematised, from these:root
variables will be made
-
-
color
- define site colours-
tokens
- these are the colour names, such asred-600
, not super human readable, from these:root
variables will be made -
borderColor
- apply colour tokens (or arbitrary colours) to human readable systematised named classes, eg:border-primary
for your primary border, might map toprimary: grey-5
, from these:root
variables will be made textColor
- same for text classesbackgroundColor
- and background colours
-
-
typography
- define the site type styles-
families
- firstly the families being used, from these:root
variables will be made -
typesets
- responsive type sets, where breakpoint overrides can be specified and typography can be systematised
-
Tailwind 4 tailwind.config.js and input.css
// A17 tailwind plugins
const {
Setup,
ColorTokens,
ApplyColorVariables,
Typography,
Container,
DevTools,
GridGap,
GridLayout,
Spacing,
Layout,
GridLine,
Keyline,
BackgroundFill,
StrokeFull,
Underline,
FullBleedScroller,
Scrollbar,
PseudoElements,
InteractionMediaQueries,
RatioBox,
} = require('../index');
// conf
const feConfig = require('./frontend.config.json');
module.exports = {
content: ['./docs/**/*.html', './docs/*.html'],
plugins: [
Setup,
ColorTokens,
ApplyColorVariables,
Typography,
Container,
DevTools,
GridGap,
GridLayout,
Spacing,
Layout,
GridLine,
Keyline,
BackgroundFill,
StrokeFull,
Underline,
FullBleedScroller,
Scrollbar,
PseudoElements,
InteractionMediaQueries,
RatioBox,
],
theme: {
screens: feConfig.structure.breakpoints,
mainColWidths: feConfig.structure.container,
innerGutters: feConfig.structure.gutters.inner,
outerGutters: feConfig.structure.gutters.outer,
columnCount: feConfig.structure.columns,
fontFamilies: feConfig.typography.families,
typesets: feConfig.typography.typesets,
spacingGroups: feConfig.spacing.groups,
ratios: feConfig.ratios,
css: feConfig.css,
colors: feConfig.color.tokens,
borderColor: ApplyColorVariables(
feConfig.color.tokens,
feConfig.color.border
),
textColor: ApplyColorVariables(feConfig.color.tokens, feConfig.color.text),
backgroundColor: ApplyColorVariables(
feConfig.color.tokens,
feConfig.color.background
),
underlineColor: ApplyColorVariables(
feConfig.color.tokens,
feConfig.color.underline
),
scrollbarColor: {
track: ApplyColorVariables(
feConfig.color.tokens,
feConfig.color.scrollbar.track
),
thumb: ApplyColorVariables(
feConfig.color.tokens,
feConfig.color.scrollbar.thumb
),
},
},
extend: {
spacing: {
gutter: 'var(--inner-gutter)',
'outer-gutter': 'var(--outer-gutter, 0px)',
},
},
};
And then input this tailwind.config.js and configure the Tailwind theme in CSS:
@config "./tailwind.config.js";
@import "tailwindcss";
@theme {
--container-*: initial;
--breakpoint-*: initial;
--color-*: initial;
--font-*: initial;
--text-*: initial;
--tracking-*: initial;
--leading-*: initial;
--spacing: 1px;
}
@utility container {
max-width: 100%;
}
Tailwind 3 tailwind.config.js
// A17 tailwind plugins
const {
setup,
applyColorVariables,
backgroundFill,
colorTokens,
components,
container,
cssInJs,
devTools,
fullBleedScroller,
gridGap,
gridLayout,
gridLine,
interactionMediaQueries,
keyline,
layout,
pseudoElements,
ratioBox,
scrollbar,
spacing,
spacingTokens,
strokeFull,
typography,
underline,
} = require('../index');
// conf
const feConfig = require('./frontend.config.json');
module.exports = {
content: ['./docs/**/*.html', './docs/*.html'],
corePlugins: {
container: false,
},
plugins: [
setup,
colorTokens,
components,
backgroundFill,
container,
cssInJs,
devTools,
fullBleedScroller,
gridGap,
gridLayout,
gridLine,
interactionMediaQueries,
keyline,
layout,
pseudoElements,
ratioBox,
scrollbar,
spacing,
strokeFull,
typography,
underline,
],
theme: {
screens: feConfig.structure.breakpoints,
mainColWidths: feConfig.structure.container,
innerGutters: feConfig.structure.gutters.inner,
outerGutters: feConfig.structure.gutters.outer,
columnCount: feConfig.structure.columns,
fontFamilies: feConfig.typography.families,
typesets: feConfig.typography.typesets,
spacingGroups: feConfig.spacing.groups,
spacing: spacingTokens(feConfig.spacing.tokens),
colors: feConfig.color.tokens,
borderColor: applyColorVariables(
feConfig.color.tokens,
feConfig.color.border
),
textColor: applyColorVariables(feConfig.color.tokens, feConfig.color.text),
backgroundColor: applyColorVariables(
feConfig.color.tokens,
feConfig.color.background
),
underlineColor: applyColorVariables(
feConfig.color.tokens,
feConfig.color.underline
),
scrollbarColor: {
track: applyColorVariables(
feConfig.color.tokens,
feConfig.color.scrollbar.track
),
thumb: applyColorVariables(
feConfig.color.tokens,
feConfig.color.scrollbar.thumb
),
},
ratios: feConfig.ratios,
components: feConfig.components,
css: feConfig.css,
extend: {
minHeight: ({ theme }) => theme('spacing'),
maxWidth: ({ theme }) => theme('spacing'),
spacing: {
'safe-top': 'env(safe-area-inset-top)',
'safe-bottom': 'env(safe-area-inset-bottom)',
'safe-left': 'env(safe-area-inset-left)',
'safe-right': 'env(safe-area-inset-right)',
gutter: 'var(--inner-gutter)',
'outer-gutter': 'var(--outer-gutter, 0px)',
},
},
},
};
@tailwind base;
@tailwind components;
@tailwind utilities;