In this lesson, we’ll learn about how to make our code efficient to avoid having repetitive groups.

Why do we need components?

As you might’ve expected, no matter how useful Tailwind classes are, we’ll soon realize that we have repeating groups of utilities in our code. Of course, this makes the code error prone and hard to maintain. This is where we can use components.

What are components?

Components are predefined sets of utilities that can be reused and adapted for various scenarios. A component effectively allows us to reuse Tailwind’s classes, which reduces code repetition and improves maintainability.

Tailwind allows us to extract classes into reusable components in two major ways.

  • The first way is to just extract them as groups of classes.

  • The second way is to create a reusable component with a front-end framework like Vue or React, or a template partial with a template engine like Twig or Blade.

We’ll explore both scenarios in the following sections.

Creating an index.html file

But before we dive into the examples, let’s create an index.html file in the root directory and add links to the generated tailwind.css file and to the Font Awesome icons. Here’s what the starter template should look like:

Press + to interact
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="tailwind.css">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<!--...-->
</body>
</html>

Extracting classes into reusable components

Extracting classes into components is as easy as grouping a series of classes by using the @apply directive. To demonstrate how this can be done, we’ll create an alert component. First, let’s see how our alert component looks when it’s built only with utility classes:

Press + to interact
<div class="alert alert-info m-6 w-1/3">
<div class="alert-title alert-info-title">Info</div>
<div class="alert-content alert-info-content">
Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
</div>

As we can see, this code sample creates a simple “Info” alert component. But the problem is that if we want to create different alerts—such as the “Warning” and “Success” alerts—we’ll need to repeat a big part of the code for each alert. This leads to poor maintainability because if we want to change the overall styles of these alerts, we’ll need to update each one separately. To avoid such a scenario, we’ll extract the repeating patterns into individual component classes.

So, we’ll open the styles.css file and add some code to it. Click the “Run” button to see our app.

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, 
                                   initial-scale=1.0" />
    <link rel="stylesheet" type="text/css" href="tailwind.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  </head>
  <body>
    <div class="alert alert-info m-6 w-1/3">
      <div class="alert-title alert-info-title">Info</div>
      <div class="alert-content alert-info-content">Lorem ipsum dolor 
                                                    sit amet consectetur 
                                                    adipisicing elit.</div>
    </div>  
  </body>
</html>
Adding an info alert

Note: You can find the output by clicking the URL and the output tab.

  • Line 6: Here, we’ve used the @layer components { ... } directive to wrap our custom component classes. This is to tell Tailwind which layer those styles belong to and to avoid specificity issues. The options are base, components, and utilities.

  • Lines 7–15: First, we extract the base code for each alert component part into an individual class (.alert, .alert-title, and .alert-content).

  • Lines 16–24: Then, we extract the code that differs for each individual alert (the specific color classes). For example, for the “Info” alert, the classes would be .alert-info, .alert-info-title, and .alert-info-content. Generally, we extract or group the utilities into smaller and more manageable component classes.

Advantage of Tailwind’s classes

As you might’ve noticed, the classes we’ve just created are pretty similar to those in component-based frameworks such as Bootstrap or Bulma. The advantage of Tailwind’s classes is that they’re more transparent and easier to tweak. We can see exactly which utilities are applied, and we can easily edit them whenever we need to.

Adding another alert

Once we’ve created the required classes, we can try out the new components in action. We’ll open the index.html file and add some code to it.

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" type="text/css" href="tailwind.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  
  </head>
  <body>
    <div class="alert alert-info m-6 w-1/3">
      <div class="alert-title alert-info-title">Info</div>
      <div class="alert-content alert-info-content">
        Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    </div>  
    <div class="alert alert-warning m-6 w-1/3">
      <div class="alert-title alert-warning-title">Warning</div>
      <div class="alert-content alert-warning-content">
        Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    </div>
  </body>
</html>
Adding a warning alert

This code creates “Info” and “Warning” alerts.

As you can see, with our custom component classes, we can create much more manageable and maintainable code. We now have fewer classes to use and fewer places to make changes.