Twin blends the magic of Tailwind with the flexibility of css-in-js
Demo twin on CodeSandbox β
Use Twinβs tw
prop to add Tailwind classes onto jsx elements:
import 'twin.macro'
const Input = () => <input tw="border hover:border-black" />
Nest Twinβs tw
import within a css prop to add conditional styles:
import tw from 'twin.macro'
const Input = ({ hasHover }) => (
<input css={[tw`border`, hasHover && tw`hover:border-black`]} />
)
Or mix sass styles with the css import:
import tw, { css } from 'twin.macro'
const hoverStyles = css`
&:hover {
border-color: black;
${tw`text-black`}
}
`
const Input = ({ hasHover }) => (
<input css={[tw`border`, hasHover && hoverStyles]} />
)
Styled Components
You can also use the tw import to create and style new components:
import tw from 'twin.macro'
const Input = tw.input`border hover:border-black`
And clone and style existing components:
const PurpleInput = tw(Input)`border-purple-500`
Switch to the styled import to add conditional styling:
import tw, { styled } from 'twin.macro'
const Input = styled.input(({ hasHover }) => [
`color: purple;`,
tw`border rounded`,
hasHover && tw`hover:border-black`,
])
const Component = () => <Input hasHover />
Or use backticks to mix with sass styles:
import tw, { styled } from 'twin.macro'
const Input = styled.input`
color: purple;
${tw`border rounded`}
${({ hasHover }) => hasHover && tw`hover:border-black`}
`
const Component = () => <Input hasHover />
How it works
When babel runs over your code, Twinβs css
and styled
imports get swapped with the real imports from libraries like
Twin offers import presets for both libraries or you can fully customise the imports.
When you use tw
, Twin converts your classes into css objects, ready for passing to your chosen css-in-js library:
import tw from 'twin.macro'
tw`text-sm md:text-lg`
// β β β β β β
{
fontSize: '0.875rem',
'@media (min-width: 768px)': {
fontSize: '1.125rem',
},
}
Features
β ml-7 was not found
Try one of these classes:
ml-0 [0] / ml-1 [0.25rem] / ml-2 [0.5rem] / ml-3 [0.75rem] / ml-4 [1rem] / ml-5 [1.25rem] / ml-6 [1.5rem]
ml-8 [2rem] / ml-10 [2.5rem] / ml-12 [3rem] / ml-16 [4rem] / ml-20 [5rem] / ml-24 [6rem] / ml-32 [8rem]
ml-40 [10rem] / ml-48 [12rem] / ml-56 [14rem] / ml-64 [16rem] / ml-auto [auto] / ml-px [1px]
import { theme, css } from 'twin.macro'
const Input = () => <input css={css({ color: theme`colors.purple.500` })} />
See more examples using the theme import β
tw`hidden!`
// β β β β β β β β β
{ "display": "none !important" }
- Prefix with
before:
andafter:
to style pseudo-elements - Prefix with
hocus:
to style hover + focus at the same time - Style with extra group states like
group-hocus:
andgroup-active:
- Style form field states with
checked:
,invalid:
andrequired:
- Stack up variants whenever you need them
sm:hover:first:bg-black
Check out the full list of variants β
import 'twin.macro'
const interactionStyles = () => (
<div tw="hover:(text-black underline) focus:(text-blue-500 underline)" />
)
const mediaStyles = () => <div tw="sm:(w-4 mt-3) lg:(w-8 mt-6)" />
const pseudoElementStyles = () => (
<div tw="before:(content block w-10 h-10 bg-black)" />
)
const stackedVariants = () => <div tw="sm:hover:(bg-black text-white)" />
const variantsInGroups = () => <div tw="sm:(bg-black hover:bg-white)">
Get started
Take a look at these examples to get started:
React
Preact
Create React App
Gatsby
Next.js
Snowpack
Storybook
Monorepo component library
Laravel
Vue
Plugins
You can use many Tailwind plugins with twin, like tailwindcss-typography and @tailwindcss/forms but thereβs no compatibility with plugins that use the addVariant
function.
See list of supported plugins β
TypeScript
Twin fully supports TypeScript projects and includes types for every import except the css
and styled
imports.
How to add the missing css
and styled
types β
Community
Drop into our Discord server for announcements, help and styling chat.
Resources
- Create advanced themes with css variables
- Sync your screen breakpoints with javascript
- Twin vscode snippits for easier imports
- Use the official vscode intellisense extension with twin
- Tailwind class cheat sheet
- "Why I Love Tailwind" by Max Stoiber
Special thanks
This project stemmed from babel-plugin-tailwind-components so a big shout out goes to Brad Cornes for the amazing work he produced. Styling with tailwind.macro has been such a pleasure.