Use Tailwind classes within any CSS-in-JS library with Twin

To use Tailwind – or any prebuilt CSS library/framework for that matter – in a React app you can simply import its generated CSS file and use the classes it exposes:

import '../tailwind.generated.css';

// …

const Alert = ({ title = '', message }) => (
    <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
        {title && <strong class="font-bold">{title}</strong>}
        <span class="block sm:inline">{message}</span>
        <span class="absolute top-0 bottom-0 right-0 px-4 py-3">
            <svg class="fill-current h-6 w-6 text-red-500" role="button" xmlns="" viewBox="0 0 20 20">
                <path d="M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697l2.758-3.15-2.759-3.152a1.2 1.2 0 1 1 1.697-1.697L10 8.183l2.651-3.031a1.2 1.2 0 1 1 1.697 1.697l-2.758 3.152 2.758 3.15a1.2 1.2 0 0 1 0 1.698z" />

But what if you want to combine Tailwind with 💅 styled-components or 👩‍🎤 emotion? This is where Twin comes in handy:

import React from 'react'
import tw from 'twin.macro'
import styled from '@emotion/styled/macro'
import { css } from '@emotion/core'

const Input = styled.input`
  ${({ hasHover }) => hasHover && tw`hover:border-black`}
  color: white;
export default () => <Input hasHover />

tw will extract the styles from the classes so that the CSS-in-JS Library can use it.

twin.macro →

💡 To work with CSS Class Names in React you can use the classnames package or an implementation on top of it such as classnames-components. I personally prefer one of these methods as these packages allow me to still write my CSS in CSS … #separationofconcerns #embracetheplatform

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.