Tailwindcss ❤ React
Recently, I tried using TailwindCSS (opens new window)in a React project bootstrapped by the Create-React-App (CRA) boilerplate and ran into difficulties setting up TailwindCSS as CRA abstracts configuration. To make custom configurations, we would have to eject Create-React-App to have full access to tinker with the configurations, which also means a much more tedious setup and should anything break…you’re on your own. I tinkered with it a bit and found a better way to get it done.
In this post, I will be showing an easy way to make TailwindCSS work inside your react CRA project without having to eject Create-React-App.
This tutorial assumes basic knowledge of TailwindCSS and React JS.
Prerequisites
- Knowledge of how npm works
- Have Node.js 8.0 or higher and npm 5.2 or higher installed
- Basic understanding of React JS and TailwindCSS
Getting started
First, open your terminal and type the following commands to create a new project.
# Using NPM
$ npx create-react-app tailwindreact-app
# Using Yarn
$ yarn create react-app tailwindreact-app
This bootstraps a new react app with all the necessary configurations and build pipelines (Webpack, Babel).
cd into your app directory.
cd tailwindreact-app
Next, install Tailwind:
# Using npm
npm install tailwindcss --save-dev
# Using Yarn
yarn add tailwindcss --dev
Create the default configurations scaffold. npx tailwind init tailwind.js --full This command creates a tailwind.js in your project’s base directory, the file houses all of Tailwind’s default configuration.
Install Autoprefixer and PostCSS-CLI like this:
npm install postcss-cli autoprefixer --save-dev
or
yarn add postcss-cli autoprefixer --save-dev
As stated in the PostCSS documentation:
PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.
While Autoprefixer is a PostCSS plugin, it basically parses your CSS and adds/removes unnecessary vendor prefixes in your compiled CSS rules. It can help you add prefixes for animations, transition, transform, grid, flex, flexbox, etc.
How to configure PostCSS
Create a PostCSS configuration file in your base directory manually or using the command:
$ touch postcss.config.js
Add the following lines of code to your PostCSS file:
//postcss.config.js
const tailwindcss = require('tailwindcss');
module.exports = {
plugins: [
tailwindcss('./tailwind.js'),
require('autoprefixer'),
],
};
Inside your src folder create a folder, name it styles , this is where all your styles would be stored. Inside that folder, create a tailwind.css and an index.css file.
The index.css file is where we would be importing tailwind’s base styles and configurations, while the tailwind.css would contain the compiled output of the index.css.
How to inject tailwind’s components, utilities and base styles to your app
Add the following to your index.css file.
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind is a tailwind directive that is used to inject default base styles, components, utilities and custom configurations.
@tailwind base — This injects Tailwind’s base styles, which is a combination of Normalize.css and some additional base styles.
For a complete reference of all the styles applied by Preflight, see this stylesheet.
If you’re using postcss-import, use this import instead:
@import "tailwindcss/base";
@tailwind components — This injects any component (small reusable styles like buttons and form elements, etc) classes registered by plugins defined in your tailwind config file.
If you’re using postcss-import, use this import instead:
@import "tailwindcss/components";
Below the component import is where you would add any of your custom component classes; stuff that you’d want loaded before the default utilities so the utilities could still override them.
Here’s an example:
.btn { ... }
.form-input { ... }
Or if using a preprocessor or postcss-import:
@import "components/buttons";
@import "components/forms";
@tailwind utilities — This injects all of Tailwind’s utility classes(including the default and your own utilities) they are generated based on your config file.
If using postcss-import, use this import instead: @import "tailwindcss/utilities"; Below the utilities import is where you would add any custom utilities you need that don’t come out of the box with Tailwind.
Here is an example:
.bg-pattern-graph-paper { ... }
.skew-45 { ... }
Or if using a preprocessor or postcss-import:
@import "utilities/background-patterns";
@import "utilities/skew-transforms";
Tailwind will swap all these directives out at build time and replace them with the CSS generated.
How to configure your app to build your CSS file
Configure your app to build the styles every time you run the npm start or yarn start command.
Open your package.json file and replace the content of "scripts" with:
"scripts": {
"build:style":"tailwind build src/styles/index.css -o src/styles/tailwind.css",
"start": "npm run build:style && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
How to import your CSS to the app Open your index.js file and import your tailwind styles.
import './styles/tailwind.css';
Delete the index.css and app.css files in your projects root directory and remove their corresponding import statements in both the Index.js and App.js files respectively.
Your index.js file should look similar to this:
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
.......
After deletion it should become:
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
Your App.js file should look like this before deletion:
//App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';
After deletion it should become:
//App.js
import React from 'react';
import logo from './logo.svg';
These changes would cause an output similar to this:
Output in your browser after deleting your index.css and app.css To test that our configurations work correctly let’s create a simple sign-in form.
Open your App.js file and replace the content between the return function with:
<div className="App" >
<div className="w-full max-w-md bg-gray-800" >
<form action="" className=" bg-white shadow-md rounded px-8 py-8 pt-8">
<div className="px-4 pb-4">
<label htmlFor="email" className="text-sm block font-bold pb-2">EMAIL ADDRESS</label>
<input type="email" name="email" id="" className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline border-blue-300 " placeholder="Johnbull@example.com"/>
</div>
<div className="px-4 pb-4">
<label htmlFor="password" className="text-sm block font-bold pb-2">PASSWORD</label>
<input type="password" name="email" id="" className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline border-blue-300" placeholder="Enter your password"/>
</div>
<div>
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="button">Sign In</button>
</div>
</form>
</div>
</div>
What we’ve just done is we gave the div a width of 100% with w-full , we also set the max-width with max-w-md for medium screens and larger.
We gave the form a white background with bg-white and gave it a border-radius to achieve the curved borders with border, px-8 and py-8 adds a padding of 8px to the x-axis and y-axis respectively while pt-8 adds a padding of 8px to the top of the form.
We added font-size of .875rem to the label element with text-sm and made the element have a display of block and set the font-weight to a value of 700 with font-bold.
On the input element, we gave the element some box-shadow with shadow and used .appearance-none to reset any browser-specific styling on the input element.
We added a line-height of 1.25 with leading-tight and used the pseudo-class focus to remove browser-specific outlining of the focused input element with focus:outline-none and added a bit of box-shadow with focus:shadow-outline.
You should get a result similar to this.
Conclusion
With small and simple steps it is possible to youse tailwind in your react projects. This post offer you a step by step manual on how to implement it. You are welcome for feedback and suggestions 👍.