Build a Website with React and Tailwind CSS

This tutorial shows how to create a product website using React and Tailwind CSS. We’ll cover how to set up React with Tailwind CSS using Create React App Configuration Override (CRACO); Tailwind’s CSS utility classes and variants and how to use them; how to easily make the website dark mode compatible; what groups are; and how to enable variants.

You can view a demo of the website we’re creating here, and you can find the code for this repository on this GitHub repository.


Before we start, you need to have Node.js and npm installed. If you have Node.js installed, then you’ll have npm installed.

To check if Node is installed, run the following in the command line:

node -v 

You should be able to see the version. Do the same for npm:

npm -v 

It should be noted that Tailwind CSS requires Node.js version 12.13.0 or higher.

If you get an error for either, then you have to install Node. You can follow the installation instructions on the Node website, or you can follow along with our article “Installing Multiple Versions of Node.js Using nvm”.

Setting Up React and Tailwind CSS

Note: if you’re unfamiliar with Create React App, check out “Create React App: Get React Projects Ready Fast” first.

First, create a React project with create-react-app:

npx create-react-app react-shop 

Then, change directory to the created project:

cd react-shop 

Next, we’ll install the dependencies required for Tailwind CSS:

npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9 

We’re installing Tailwind CSS with the PostCSS 7 compatibility build, as Create React App (or CRA) does not support PostCSS 8 at the time of writing this article. We’re also installing autoprefixer, as it’s required for Tailwind CSS after version 2.0.

Setting Up CRACO

Usually, to configure CRA you need to run react-scripts eject or npm run eject with the default scripts of CRA. However, this is very inconvenient, as it will eject all the configurations that are hidden in CRA (like webpack configurations, Babel configurations, PostCSS configurations, and much more) into your project, and editing it can become a hassle or produce issues that CRA will no longer be able to support.

This is where Create React App Configuration Override (or CRACO) comes in. CRACO is a library that adds a simple configuration layer to CRA. Instead of ejecting all the configurations inside CRA into your project — for example, just to add some configuration to Webpack — all new configurations or changes to the original configuration will be put in a new file craco.config.js. CRACO allows you to configure CRA to get the best out of it without the hassle.

We need CRACO here to override PostCSS configurations and add the tailwindcss plugin. So, let’s first install it:

npm install @craco/craco 

When using CRA, the scripts in package.json look like this:

"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" } 

As we’re using CRACO to do what we can’t do with CRA by default, we need to change the scripts to use CRACO for building the project or running it in development:

"scripts": { "start": "craco start", "build": "craco build", "test": "craco test", "eject": "react-scripts eject" }, 

We’ve replaced react-scripts with craco in the start, build and test scripts. We haven’t make any changes to the eject script.

Next, create the CRACO configuration file craco.config.js in the root of the project:

module.exports = { style: { postcss: { plugins: [ require('tailwindcss'), require('autoprefixer'), ], }, }, } 

This configuration file adds the tailwindcss and autoprefixer plugins to postcss.

Now we’ll generate the configuration file for Tailwind CSS:

npx tailwindcss init 

Note: if you’re using Node.js v14, there’s a reported issue about an error thrown while running this command that says “Cannot find module ‘autoprefixer’”. Updating to Node.js v15 should work, but if you’re unable to do that, please follow one of the workarounds here.

This will create the file tailwind.config.js in the root of the project. It will have the following content:

module.exports = { purge: [], darkMode: false, // or 'media' or 'class' theme: { extend: {}, }, variants: { extend: {}, }, plugins: [], } 

Here’s what each of the configuration keys means:

  1. purge: this is used to specify the files Tailwind CSS should scan and see which Tailwind CSS classes are being used, so that it can remove all unused styles and classes in production.
  2. darkMode: this specifies the behavior of dark mode in your project. The value can be media — meaning that the dark mode styling will be applied based on the dark mode media query, which depends on the default mode for the user’s OS. It can also be class, which means that the dark mode styling will be applied when a parent element in the HTML document has the dark class.
  3. theme: this can be used to modify the color palette of the theme, fonts, breakpoints, and more. We’ll see how to make changes to the theme later in the tutorial.
  4. variants: this allows you to apply additional variants to the core plugins of Tailwind CSS. We’ll see how it works later on in the tutorial.
  5. plugins: a section to add plugins that can add extra utility classes, custom variants, base styles or more.

For now, we’ll just make two changes. First, we’ll change the purge key:

purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"], 

This tells Tailwind CSS to look through all js, jsx, ts and tsx files in the src directory, and the public/index.html file to figure out which classes will be used from Tailwind CSS and remove any unused classes.

The second change will be for dark mode:

darkMode: "media", // or false or 'class' 

For the sake of simplicity in this tutorial, we’ll keep dark mode just based on the user’s OS preference.

The final step in setting up our React project with Tailwind CSS is to include some of the Tailwind CSS styles in src/index.css. Replace the contents of this file with the following:

@tailwind base; @tailwind components; @tailwind utilities; 

The @tailwind directive basically imports the styles into index.css. And by default, CRA imports src/index.css in src/index.js:

import './index.css'; 

This means that Tailwind CSS styles will be applied in our React project, and we’re ready to start building a beautiful website!

Understanding Tailwind CSS Utilities and Variants

Before getting into the coding, let’s understand what Tailwind CSS utility classes and variants are. Tailwind CSS is designed to make styling components easier and help you focus on making reusable components. Utility classes are a wide range of classes that allow you to style your component in any way you can think of without writing any CSS.

For example, to style a <div> element with a border, change font size, change background and text color, you’ll need to write something like this with CSS:

div { border: 1px solid #f00; font-size: 15px; background-color: #ff007f; color: #fff; } 

Using Tailwind CSS, you can do it just using the utility classes:

<div class="border border-red-100 text-lg bg-red-400 text-white"> </div> 

Here’s what each class means in this example:

  1. border: sets border width to 1px
  2. border-red-100: sets border color to a shade of red (based on the theme)
  3. text-lg: gives font size 1.125rem and line height 1.75rem
  4. bg-red-400: sets background color to a shade of red (based on the theme)
  5. text-white: sets text color to white

There are many other classes you can use, with many different shades of colors as well, which makes theming easier. Using the utility classes, you rarely need to actually write any CSS at all.

Okay, but what about media queries? What about psuedo classes? What about dark mode? Can these be done without having to write any CSS yourself?

That’s when variants come in. Variants allow you to add styling to elements based on device breakpoints, states of elements, or whether dark mode is enabled or not.

So, previously you might have done this to change the width of an element based on the size of the device:

div { width: 50%; } @media screen and (max-width: 1024px) and (min-width: 768px) { div { width: 80%; } } @media screen and (max-width: 767px){ div { width: 100% } } 

With Tailwind CSS, it can be simply done as this:

<div class="w-full md:w-3/4 lg:w-1/2"> </div> 

This applies the w-1/2 class (which means width: 50%) when min-width: 1025px applies to the current screen width, applies w-3/4 class (which means width: 80%) when min-width: 768px applies to the current screen width, and applies w-full class (which means width: 100%;) when the other variants don’t apply anymore.

This definitely makes the tedious work you have to do in every project easier and faster. At first, it might look confusing, but when you start dabbling in it more you’ll realize how it becomes second nature to use the utility classes and variants.

You can read more about configuring Tailwind in the project’s official documentation.

Continue reading Build a Website with React and Tailwind CSS on SitePoint.

Similar Posts