React JS web app with Tailwind CSS

Front-end development is a crucial aspect of any web development aspect. It is the first impression that the users get and is, therefore, all the more important in shaping user experiences. Creating user-friendly and visually appealing designs is essential, and fortunately, this process can be expedited with the help of various tools.

Tailwind CSS

Tailwind CSS is a low-level CSS framework, and it offers various utility styling options for different components of the code. It consists of predefined class names that can be coupled to make up highly customizable objects. Tailwind CSS is quite similar to CSS and uses the same styling concepts.

Tailwind logo
Tailwind logo

React and Tailwind CSS

React and Tailwind CSS can be used to create modern and responsive web applications. React provides the foundation for building dynamic UI components, while Tailwind CSS complements React by offering a set of utility classes for styling these components.

A simple Tailwind code
A simple Tailwind code

Setting up a React JS project

A React JS project will be needed to implement Material UI components inside it. This can be done by following the steps given here.

Alternatively, these two commands can be run to set up the project quickly.

npx create-react-app react-proj
cd react-proj

Project structure

Project structure of a simple React project
Project structure of a simple React project

Installation of Tailwind CSS

Tailwind needs to be configured in our React project before we can start using it first. Once our React project has been set up, we need to follow the below-mentioned steps to complete setting up Tailwind CSS.

Install Tailwind CSS

  • We can quickly set up Tailwind CSS from scratch using the Tailwind CLI tool.

  • To install Tailwind CSS, let's use npmNode's package manager.

npm install -D tailwindcss

Next, we create a tailwind.config.js file.

npx tailwindcss init

Configure paths

  • In the tailwind.config.js file, we add the paths to our template files. This specifies where Tailwind should scan for styles and can be modified.

module.exports = {
content: ["./src/**/*.{html,js}"],
theme: {
extend: {},
},
plugins: [],
};

Add Tailwind Directives to CSS

  • We need to add Tailwind directives to our CSS file so that our styles can become visible.

  • In our main CSS file, we add the following Tailwind directives.

@tailwind base;
@tailwind components;
@tailwind utilities;
Updated folder structure
Updated folder structure

Official documentation of Tailwind CSS

Tailwind CSS provides a corresponding customized class name for mostly all of the CSS classes. These names can be mapped to the style that is needed, and the Tailwind class name can be written inside the className tag.

Using these Tailwind CSS class names, developers can easily apply styles without writing separate CSS files or custom styles.

Note: The detailed style guide can be found in the official documentation found here.

Code sample

<div className="text-center bg-blue-500 py-8 px-12 text-white text-4xl font-bold shadow-lg rounded-lg h-[100vh]">
<h2 className = 'underline'>Hello Educative!</h2>
<p className="mt-4 text-lg ">Unlock your learning potential.</p>
<button className="mt-8 text-lg bg-white text-blue-500 py-2 px-4 rounded-md shadow-md hover:bg-blue-500 hover:text-white">
Learn More
</button>
</div>

Let's make a div element with the following Tailwind CSS class names.

  • className: Specifies the class names for styling the component.

  • "text-center": Centers the text horizontally within the <div>.

  • "underline": Adds an underline to the text.

  • "bg-blue-500": Sets the background color to a shade of blue.

  • "py-8": Adds padding on the y-axis with a size of 8.

  • "px-12": Adds padding on the x-axis with a size of 12.

  • "text-white": Sets the text color to white.

  • "text-4xl": Sets the font size to 4xl i.e. extra large.

  • "font-bold": Applies a bold font weight to the text.

  • "shadow-lg": Adds a shadow effect to the component.

  • "rounded-lg": Rounds the corners of the component.

  • "h-[100vh]": Sets the height of the component to 100 viewport height units.

  • The content inside the <div> includes the following:

    • The text "Hello Educative!" is the main heading.

    • A <p> element with class name "mt-4 text-lg", which adds a margin-top mt-4 of 4 and sets the font size text-xl to large.

    • A <button> element with class names "mt-8 text-lg bg-white text-blue-500 py-2 px-4 rounded-md shadow-md hover:bg-blue-500 hover:text-white". It has styling for background color, text color, padding, rounded corners, shadow, and hover effects. The button text is "Learn More".

Complete code

The component SimpleTCSS.jsx contains the code for the HelloEducative component and it is then rendered in App.js.

import React, { useEffect, useState } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";

 const options = {

    fps_limit: 60,
    interactivity: {
      detect_on: "canvas",
      events: {
        onclick: { enable: false, mode: "push" },
        onhover: {
          enable: false,
          mode: "attract",
          parallax: { enable: false, force: 60, smooth: 10 },
        },
        resize: true,
      },
      modes: {
        push: { quantity: 4 },
        attract: { distance: 200, duration: 0.4, factor: 5 },
      },
    },
    particles: {
      color: { value: "#ffffff" },
      line_linked: {
        color: "#ffffff",
        distance: 150,
        enable: true,
        opacity: 0.3,
        width: 1,
      },
      move: {
        attract: { enable: false, rotateX: 600, rotateY: 1200 },
        bounce: false,
        direction: "none",
        enable: true,
        out_mode: "out",
        random: false,
        speed: 0.4,
        straight: false,
      },
      number: { density: { enable: true, value_area: 800 }, value: 80 },
      opacity: {
        anim: { enable: false, opacity_min: 0, speed: 1, sync: false },
        random: false,
        value: 0.1,
      },
      shape: {
        character: {
          fill: false,
          font: "Verdana",
          style: "",
          value: "*",
          weight: "400",
        },
        image: {
          height: 100,
          replace_color: true,
          src: "images/github.svg",
          width: 100,
        },
        polygon: { nb_sides: 5 },
        stroke: { color: "#000000", width: 0 },
        type: "circle",
      },
      size: {
        anim: { enable: false, size_min: 0.1, speed: 40, sync: false },
        random: true,
        value: 5,
      },
    },
    polygon: {
      draw: { enable: false, lineColor: "#ffffff", lineWidth: 0.5 },
      move: { radius: 10 },
      scale: 1,
      type: "none",
      url: "",
    },
    retina_detect: true,
  };
  
const Landing = () => {

  const particlesInit = async (main) => {
    await loadFull(main);
  };

  
  function handleGetStartedClick() {
    alert("You clicked me!")
  }

  const particlesLoaded = (container) => {};

  useEffect(() => {
    function handleScroll() {
      const heading = document.querySelector(".card");
      const scrollPosition = window.scrollY;
      const opacity = 1 - scrollPosition / 300;

      const heading2 = document.querySelector(".info");
      const scrollPosition2 = window.scrollY;
      const opacity2 = -1 + scrollPosition2 / 350;

      heading.style.opacity = opacity;
      heading2.style.opacity = opacity2;
    }

    window.addEventListener("scroll", handleScroll);

    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return (
    <div className="h-[200vh]">
      <div className="card h-screen flex flex-col items-start justify-end pl-20 pb-8 text-white">
        <p className="text-5xl">&lt; Hello there, this is </p>
        <p className="text-4xl text-red-900 pl-8"> Educative /&gt; </p>
      </div>
      <div className="info flex flex-col items-center justify-end text-white mt-24">
        <p className="text-9xl font-medium p-0 mb-8"> Web Dev</p>
        <div className="w-[40vw] bg-black/50 rounded p-8 text-justify text-lg">
          <p>
             Educative Answers is a free web encyclopedia written by devs for devs. Find the answers you need with our short, verified articles that feature executable code, or join the community and become a contributor.
          </p>
        </div>
        <button className="mt-8 text-2xl transform transition-all duration-300 w-full z-10 hover:scale-90" 
        onClick={handleGetStartedClick}
        >
          Let's get started <br />
          <p className="text-7xl">&rarr;</p>
        </button>
      </div>

      <Particles
        init={particlesInit}
        loaded={particlesLoaded}
        options={options}
      />
    </div>
  );
};

export default Landing;

Output

The output of the above Tailwind CSS-styled React component is given below. Yay, we were able to style a heading, paragraph, and button in just a few lines of code!

The output of HelloEducative component
The output of HelloEducative component

The button being hovered
The button being hovered

Full fledge landing page scenario

Let's take a more developed and fun example of using Tailwind CSS. We'll be creating a complete landing page for a fictional website.

Setup

To run the code below, configure Tailwind by following the steps we talked about earlier and download the packages using the command below.

npm i react-router-dom react-tsparticles tsparticles

Note: We use React tsParticles to create an aesthetic background containing particles.

Let's take a look at the complete code below.

import React, { useEffect, useState } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";

 const options = {

    fps_limit: 60,
    interactivity: {
      detect_on: "canvas",
      events: {
        onclick: { enable: false, mode: "push" },
        onhover: {
          enable: false,
          mode: "attract",
          parallax: { enable: false, force: 60, smooth: 10 },
        },
        resize: true,
      },
      modes: {
        push: { quantity: 4 },
        attract: { distance: 200, duration: 0.4, factor: 5 },
      },
    },
    particles: {
      color: { value: "#ffffff" },
      line_linked: {
        color: "#ffffff",
        distance: 150,
        enable: true,
        opacity: 0.3,
        width: 1,
      },
      move: {
        attract: { enable: false, rotateX: 600, rotateY: 1200 },
        bounce: false,
        direction: "none",
        enable: true,
        out_mode: "out",
        random: false,
        speed: 0.4,
        straight: false,
      },
      number: { density: { enable: true, value_area: 800 }, value: 80 },
      opacity: {
        anim: { enable: false, opacity_min: 0, speed: 1, sync: false },
        random: false,
        value: 0.1,
      },
      shape: {
        character: {
          fill: false,
          font: "Verdana",
          style: "",
          value: "*",
          weight: "400",
        },
        image: {
          height: 100,
          replace_color: true,
          src: "images/github.svg",
          width: 100,
        },
        polygon: { nb_sides: 5 },
        stroke: { color: "#000000", width: 0 },
        type: "circle",
      },
      size: {
        anim: { enable: false, size_min: 0.1, speed: 40, sync: false },
        random: true,
        value: 5,
      },
    },
    polygon: {
      draw: { enable: false, lineColor: "#ffffff", lineWidth: 0.5 },
      move: { radius: 10 },
      scale: 1,
      type: "none",
      url: "",
    },
    retina_detect: true,
  };
  
const Landing = () => {

  const particlesInit = async (main) => {
    await loadFull(main);
  };

  
  function handleGetStartedClick() {
    alert("You clicked me!")
  }

  const particlesLoaded = (container) => {};

  useEffect(() => {
    function handleScroll() {
      const heading = document.querySelector(".card");
      const scrollPosition = window.scrollY;
      const opacity = 1 - scrollPosition / 300;

      const heading2 = document.querySelector(".info");
      const scrollPosition2 = window.scrollY;
      const opacity2 = -1 + scrollPosition2 / 350;

      heading.style.opacity = opacity;
      heading2.style.opacity = opacity2;
    }

    window.addEventListener("scroll", handleScroll);

    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return (
    <div className="h-[200vh]">
      <div className="card h-screen flex flex-col items-start justify-end pl-20 pb-8 text-white">
        <p className="text-5xl">&lt; Hello there, this is </p>
        <p className="text-4xl text-red-900 pl-8"> Educative /&gt; </p>
      </div>
      <div className="info flex flex-col items-center justify-end text-white mt-24">
        <p className="text-9xl font-medium p-0 mb-8"> Web Dev</p>
        <div className="w-[40vw] bg-black/50 rounded p-8 text-justify text-lg">
          <p>
             Educative Answers is a free web encyclopedia written by devs for devs. Find the answers you need with our short, verified articles that feature executable code, or join the community and become a contributor.
          </p>
        </div>
        <button className="mt-8 text-2xl transform transition-all duration-300 w-full z-10 hover:scale-90" 
        onClick={handleGetStartedClick}
        >
          Let's get started <br />
          <p className="text-7xl">&rarr;</p>
        </button>
      </div>

      <Particles
        init={particlesInit}
        loaded={particlesLoaded}
        options={options}
      />
    </div>
  );
};

export default Landing;

The above code makes use of similar Tailwind class names as in the previous example and uses some other class names too. Let's dive deeper into a few.

className

Description

h-[200vh]

The page height is of two view ports.

h-screen

The div takes up a space of a full horizontal screen.

pl-8

A padding at the left of size 8.

flex

A display of flex is applied.

flex-col

The items in the flex are arranged in a column.

items-center

The items within the flex are centered in the column.

justify-end

The flex container is placed at the end of the space.

Tailwind-powered landing page

The following pictures show what the landing page looks like. It's styled using Tailwind CSS, and the background particles are rendered using React's tsparticles library.

svg viewer
Landing page
Landing page
Scrolling down the landing page
Scrolling down the landing page

Benefits of using Tailwind over plain CSS

  • Faster styling with pre-built utility classes.

  • Consistent design system with reusable classes.

  • Responsive layouts are made easier with Tailwind.

  • Customizable configuration for tailored styles.

  • Developer-friendly and code-readability.

  • Reduced maintenance efforts due to concise code.

  • Active community support plus extensive documentation.

A must-remember for Tailwind CSS

Question

If you miss the installation step, what would the class names do?

Show Answer

Copyright ©2024 Educative, Inc. All rights reserved