
- Tailwind CSS - Home
- Tailwind CSS - Roadmap
- Tailwind CSS - Introduction
- Tailwind CSS - Installation
- Tailwind CSS - Editor Setup
- Tailwind CSS - Utility-First Fundamentals
- Tailwind CSS - Hover, Focus, and Other States
- Tailwind CSS - Responsive Design
- Tailwind CSS - Dark Mode
- Tailwind CSS - Reusing Styles
- Tailwind CSS - Adding Custom Styles
- Tailwind CSS - Functions & Directives
- Tailwind CSS - Customization
- Tailwind CSS - Configuration
- Tailwind CSS - Content Configuration
- Tailwind CSS - Theme Configuration
- Tailwind CSS - Customizing Screens
- Tailwind CSS - Customizing Colors
- Tailwind CSS - Customizing Spacing
- Tailwind CSS - Plugins
- Tailwind CSS - Presets
- Tailwind CSS - Base Styles
- Tailwind CSS - Preflight
- Tailwind CSS - Layout
- Tailwind CSS - Aspect Ratio
- Tailwind CSS - Container
- Tailwind CSS - Columns
- Tailwind CSS - Break After
- Tailwind CSS - Break Before
- Tailwind CSS - Break Inside
- Tailwind CSS - Box Decoration Break
- Tailwind CSS - Box Sizing
- Tailwind CSS - Display
- Tailwind CSS - Floats
- Tailwind CSS - Clear
- Tailwind CSS - Isolation
- Tailwind CSS - Object Fit
- Tailwind CSS - Object Position
- Tailwind CSS - Overflow
- Tailwind CSS - Overscroll Behavior
- Tailwind CSS - Position
- Tailwind CSS - Top / Right / Bottom / Left
- Tailwind CSS - Visibility
- Tailwind CSS - Z-Index
- Tailwind CSS - Flexbox & Grid
- Tailwind CSS - Flex Basis
- Tailwind CSS - Flex Direction
- Tailwind CSS - Flex Wrap
- Tailwind CSS - Flex
- Tailwind CSS - Flex Grow
- Tailwind CSS - Flex Shrink
- Tailwind CSS - Order
- Tailwind CSS - Grid Template Columns
- Tailwind CSS - Grid Column Start / End
- Tailwind CSS - Grid Template Rows
- Tailwind CSS - Grid Row Start / End
- Tailwind CSS - Grid Auto Flow
- Tailwind CSS - Grid Auto Columns
- Tailwind CSS - Grid Auto Rows
- Tailwind CSS - Gap
- Tailwind CSS - Justify Content
- Tailwind CSS - Justify Items
- Tailwind CSS - Justify Self
- Tailwind CSS - Align Content
- Tailwind CSS - Align Items
- Tailwind CSS - Align Self
- Tailwind CSS - Place Content
- Tailwind CSS - Place Items
- Tailwind CSS - Place Self
- Tailwind CSS - Spacing
- Tailwind CSS - Padding
- Tailwind CSS - Margin
- Tailwind CSS - Space Between
- Tailwind CSS - Sizing
- Tailwind CSS - Width
- Tailwind CSS - Min-Width
- Tailwind CSS - Max-Width
- Tailwind CSS - Height
- Tailwind CSS - Min-Height
- Tailwind CSS - Max-Height
- Tailwind CSS - Size
- Tailwind CSS - Typography
- Tailwind CSS - Font Family
- Tailwind CSS - Font Size
- Tailwind CSS - Font Smoothing
- Tailwind CSS - Font Style
- Tailwind CSS - Font Weight
- Tailwind CSS - Font Variant Numeric
- Tailwind CSS - Letter Spacing
- Tailwind CSS - Line Clamp
- Tailwind CSS - Line Height
- Tailwind CSS - List Style Image
- Tailwind CSS - List Style Position
- Tailwind CSS - List Style Type
- Tailwind CSS - Text Align
- Tailwind CSS - Text Color
- Tailwind CSS - Text Decoration
- Tailwind CSS - Text Decoration Color
- Tailwind CSS - Text Decoration Style
- Tailwind CSS - Text Decoration Thickness
- Tailwind CSS - Text Underline Offset
- Tailwind CSS - Text Transform
- Tailwind CSS - Text Overflow
- Tailwind CSS - Text Wrap
- Tailwind CSS - Text Indent
- Tailwind CSS - Vertical Align
- Tailwind CSS - Whitespace
- Tailwind CSS - Word Break
- Tailwind CSS - Hyphens
- Tailwind CSS - Content
- Tailwind CSS - Backgrounds
- Tailwind CSS - Background Attachment
- Tailwind CSS - Background Clip
- Tailwind CSS - Background Color
- Tailwind CSS - Background Origin
- Tailwind CSS - Background Position
- Tailwind CSS - Background Repeat
- Tailwind CSS - Background Size
- Tailwind CSS - Background Image
- Tailwind CSS - Gradient Color Stops
- Tailwind CSS - Borders
- Tailwind CSS - Border Radius
- Tailwind CSS - Border Width
- Tailwind CSS - Border Color
- Tailwind CSS - Border Style
- Tailwind CSS - Divide Width
- Tailwind CSS - Divide Color
- Tailwind CSS - Divide Style
- Tailwind CSS - Outline Width
- Tailwind CSS - Outline Color
- Tailwind CSS - Outline Style
- Tailwind CSS - Outline Offset
- Tailwind CSS - Ring Width
- Tailwind CSS - Ring Color
- Tailwind CSS - Ring Offset Width
- Tailwind CSS - Ring Offset Color
- Tailwind CSS - Effects
- Tailwind CSS - Box Shadow
- Tailwind CSS - Box Shadow Color
- Tailwind CSS - Opacity
- Tailwind CSS - Mix Blend Mode
- Tailwind CSS - Background Blend Mode
- Tailwind CSS - Filters
- Tailwind CSS - Blur
- Tailwind CSS - Brightness
- Tailwind CSS - Contrast
- Tailwind CSS - Drop Shadow
- Tailwind CSS - Grayscale
- Tailwind CSS - Hue Rotate
- Tailwind CSS - Invert
- Tailwind CSS - Saturate
- Tailwind CSS - Sepia
- Tailwind CSS - Backdrop Blur
- Tailwind CSS - Backdrop Brightness
- Tailwind CSS - Backdrop Contrast
- Tailwind CSS - Backdrop Grayscale
- Tailwind CSS - Backdrop Hue Rotate
- Tailwind CSS - Backdrop Invert
- Tailwind CSS - Backdrop Opacity
- Tailwind CSS - Backdrop Saturate
- Tailwind CSS - Backdrop Sepia
- Tailwind CSS - Tables
- Tailwind CSS - Border Collapse
- Tailwind CSS - Border Spacing
- Tailwind CSS - Table Layout
- Tailwind CSS - Caption Side
- Tailwind CSS - Transitions & Animation
- Tailwind CSS - Transition Property
- Tailwind CSS - Transition Duration
- Tailwind CSS - Transition Timing Function
- Tailwind CSS - Transition Delay
- Tailwind CSS - Animation
- Tailwind CSS - Transform
- Tailwind CSS - Scale
- Tailwind CSS - Rotate
- Tailwind CSS - Translate
- Tailwind CSS - Skew
- Tailwind CSS - Transform Origin
- Tailwind CSS - Interactivity
- Tailwind CSS - Accent Color
- Tailwind CSS - Appearance
- Tailwind CSS - Cursor
- Tailwind CSS - Caret Color
- Tailwind CSS - Pointer Events
- Tailwind CSS - Resize
- Tailwind CSS - Scroll Behavior
- Tailwind CSS - Scroll Margin
- Tailwind CSS - Scroll Padding
- Tailwind CSS - Scroll Snap Align
- Tailwind CSS - Scroll Snap Stop
- Tailwind CSS - Scroll Snap Type
- Tailwind CSS - Touch Action
- Tailwind CSS - User Select
- Tailwind CSS - Will Change
- Tailwind CSS - SVG
- Tailwind CSS - Fill
- Tailwind CSS - Stroke
- Tailwind CSS - Stroke Width
- Tailwind CSS - Accessibility
- Tailwind CSS - Screen Readers
- Tailwind CSS - Forced Color Adjust
- Tailwind CSS - Bonus
- Tailwind CSS - Using with Preprocessors
- Tailwind CSS - Optimizing for Production
- Tailwind CSS - References
- Tailwind CSS - Core Concepts
- Tailwind CSS - Customization
- Tailwind CSS - Layout
- Tailwind CSS - Flexbox & Grid
- Tailwind CSS - Spacing
- Tailwind CSS - Sizing
- Tailwind CSS - Typography
- Tailwind CSS - Backgrounds
- Tailwind CSS - Borders
- Tailwind CSS - Effects
- Tailwind CSS - Filters
- Tailwind CSS - Tables
- Tailwind CSS - Transitions & Animation
- Tailwind CSS - Transforms
- Tailwind CSS - Interactivity
- Tailwind CSS - Resources
- Tailwind CSS - Discussion
- Tailwind CSS - Useful Resources
Tailwind CSS - Reusing Styles
Tailwind CSS uses a utility-first approach, where you apply small, focused, single-purpose classes to build your designs. This method helps avoid complexity and maintain consistency in your code.
When working on a project, you might find yourself using the same set of utility classes in multiple places. Instead of writing custom CSS for repeated styles, you can use Tailwind's utility classes to handle these repetitions efficiently.
Here's a simple example of displaying profile widgets on a webpage using a similar utility class applied to each widget three times.
Example
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="p-4 bg-gray-100"> <div class="flex space-x-4 overflow-x-auto p-4 bg-gray-200"> <!-- Profile Widget 1 --> <div class="flex-shrink-0 w-56 p-4 bg-white border border-gray-300 rounded-lg shadow-lg flex flex-col items-center space-y-3"> <div class="mb-3"> <img class="h-20 w-20 rounded-full border-4 border-cyan-500 shadow-md" src="https://randomuser.me/api/portraits/men/1.jpg" alt="Profile Picture"/> </div> <div class="text-center"> <h3 class="text-lg font-semibold text-gray-800 mb-1">John Doe</h3> <p class="text-gray-600 text-sm mb-2">Tech Enthusiast</p> <p class="text-gray-500 text-xs">John has over 5 years of experience in the tech industry, focusing on software development and innovation. </p> </div> </div> <!-- Profile Widget 2 --> <div class="flex-shrink-0 w-56 p-4 bg-white border border-gray-300 rounded-lg shadow-lg flex flex-col items-center space-y-3"> <div class="mb-3"> <img class="h-20 w-20 rounded-full border-4 border-rose-500 shadow-md" src="https://randomuser.me/api/portraits/women/2.jpg" alt="Profile Picture"/> </div> <div class="text-center"> <h3 class="text-lg font-semibold text-gray-800 mb-1"> Jane Smith </h3> <p class="text-gray-600 text-sm mb-2">UI/UX Designer</p> <p class="text-gray-500 text-xs">Jane is a skilled UI/UX designer with 3 years of experience in creating intuitive user interfaces and enhancing user experiences. </p> </div> </div> <!-- Profile Widget 3 --> <div class="flex-shrink-0 w-56 p-4 bg-white border border-gray-300 rounded-lg shadow-lg flex flex-col items-center space-y-3"> <div class="mb-3"> <img class="h-20 w-20 rounded-full border-4 border-violet-500 shadow-md" src="https://randomuser.me/api/portraits/men/3.jpg" alt="Profile Picture"/ > </div> <div class="text-center"> <h3 class="text-lg font-semibold text-gray-800 mb-1"> Alice Johnson</h3> <p class="text-gray-600 text-sm mb-2">Data Scientist</p> <p class="text-gray-500 text-xs">Alice has 7 years of experience as a data scientist, specializing in data analysis and machine learning. </p> </div> </div> </div> </body> </html>
Don't worry! We'll help you understand how to reuse styles in your projects and when to use each method effectively.
Using Editor and Language Features
Often, repeating styles isn't a problem because it's all in one place or created with loops, so you only write the code once.
If you're working in a single file, use multi-cursor editing to make changes to several lines at once. For repeated elements, use loops to generate them from a single piece of code. This keeps your work efficient and organized.
Multi-cursor Editing
Multi-cursor editing is a feature in many text editors that enables you to place multiple cursors in different locations within a document. This allows you to make the same change in several spots all at once, making it perfect for updating repeated content quickly.
When you have repeated styles or elements in a single file, multi-cursor editing can help you modify them all at once. Let's look at an example to see how it works.
Suppose you have the following list of items and you want to update the class bg-red-100 to bg-teal-100 for each item.
Example
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="p-4"> <h3 class="font-bold underline mb-4"> List of Item in Shopping cart: </h3> <ul class="shopping-cart"> <li class="bg-red-100 p-2">Apples</li> <li class="bg-red-100 p-2">Bananas</li> <li class="bg-red-100 p-2">Oranges</li> <li class="bg-red-100 p-2">Grapes</li> </ul> </body> </html>
To Add Cursors
Hold down the Alt key and click next to each bg-red-100 in your code. This will place a cursor at each position where you clicked, and with all the cursors in place, type bg-teal-100. All instances of bg-red-100 will update to bg-teal-100 at once.
Updated Code:
<ul class="shopping-cart"> <li class="bg-teal-100 p-2">Apples</li> <li class="bg-teal-100 p-2">Bananas</li> <li class="bg-teal-100 p-2">Oranges</li> <li class="bg-teal-100 p-2">Grapes</li> </ul>
You might find that using multi-cursor editing is usually the easiest way to handle repeated styles. It helps you update all the instances at once, so you don't need extra tools or methods.
Loops
Loops in programming make it easier to handle repeated elements. Instead of writing the same code over and over, you can use a loop to create the same HTML structure automatically. So, when working with repetitive design elements in your web projects, it's important to use loops effectively.
Before you go through the effort of creating separate components or custom classes for every repeating design element, check if you're using that element more than once.
For example, the profile widgets shown at the beginning of this guide use the same design repeated three times. Instead of writing out each widget individually, we can use a loop to generate multiple elements from a single template. Let's look at how this works in the example below.
Example
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="p-4"> <div id="profile-container" class="flex space-x-4 overflow-x-auto p-4 bg-gray-200"> <!-- Profile Widgets will be dynamically inserted here --> </div> <script> document.addEventListener('DOMContentLoaded', () => { const profiles = [ { name: "John Doe", role: "Tech Enthusiast", imgSrc: "https://randomuser.me/api/portraits/men/1.jpg", borderColor: "border-cyan-500" }, { name: "Jane Smith", role: "UI/UX Designer", imgSrc: "https://randomuser.me/api/portraits/women/2.jpg", borderColor: "border-rose-500" }, { name: "Alice Johnson", role: "Data Scientist", imgSrc: "https://randomuser.me/api/portraits/men/3.jpg", borderColor: "border-violet-500" } ]; const container = document.getElementById('profile-container'); profiles.forEach(profile => { container.innerHTML += ` <div class="flex-shrink-0 w-56 p-4 bg-white border border-gray-300 rounded-lg shadow-lg flex flex-col items-center space-y-3"> <div class="mb-3"> <img class="h-20 w-20 rounded-full border-4 ${profile.borderColor} shadow-md" src="${profile.imgSrc}" alt="Profile Picture"/> </div> <div class="text-center"> <h3 class="text-lg font-semibold text-gray-800 mb-1"> ${profile.name}</h3> <p class="text-gray-600 text-sm mb-2"> ${profile.role}</p> <p class="text-gray-500 text-xs">Profile description here.</p> </div> </div> `; }); }); </script> </body> </html>
Using loop means you write the markup once, avoiding duplication and making updates easier. It efficiently manages dynamic data and ensures that changes are applied in one place.
Extracting components and partials
If you want to reuse styles in different files, it's a good idea to create a component if you're using a front-end framework like React,Swelte, or Vue. If you're using a templating language like Blade, ERB, Twig, or Nunjucks, you should create a template partial. This approach helps keep your code organized and makes it easier to maintain.
Example
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="p-4"> <div class="testimonial-sectio"> <div class="testimonial-card p-4 bg-white border border-gray-300 rounded-lg shadow-lg"> <img class="w-16 h-16 rounded-full border-2 border-gray-300" src="https://randomuser.me/api/portraits/men/1.jpg" alt="Alice Johnson's photo" /> <h3 class="mt-2 text-lg font-semibold text-gray-800"> Alice Johnson </h3> <p class="mt-1 text-gray-600"> This service is fantastic! It exceeded all my expectations. </p> </div> <div class="testimonial-card p-4 bg-white border border-gray-300 rounded-lg shadow-lg mt-4"> <img class="w-16 h-16 rounded-full border-2 border-gray-300" src="https://randomuser.me/api/portraits/women/2.jpg" alt="Bob Smith's photo" /> <h3 class="mt-2 text-lg font-semibold text-gray-800"> Bob Smith </h3> <p class="mt-1 text-gray-600"> An excellent experience from start to finish. </p> </div> </div> </body> </html>
For the example above, create a TestimonialCard component in React using Tailwind CSS and use it as many times as needed for your project. Below is a functional component you can use to display testimonials.
Example
// TestimonialCard.jsx import React from 'react'; const TestimonialCard = ({ name, photo, testimonial }) => ( <div className="p-4 bg-white border border-gray-300 rounded-lg shadow-lg"> <img className="w-16 h-16 rounded-full border-2 border-gray-300" src={photo} alt={`${name}'s photo`} /> <h3 className="mt-2 text-lg font-semibold text-gray-800">{name}</h3> <p className="mt-1 text-gray-600">{testimonial}</p> </div> ); export default TestimonialCard;
To use the TestimonialCard component in your app or design, just import it and provide the necessary props.
Example
// App.jsx import React from 'react'; import TestimonialCard from './TestimonialCard'; const App = () => ( <div className="p-4 bg-gray-100"> <div className="flex space-x-4"> <TestimonialCard name="John Doe" photo="https://randomuser.me/api/portraits/men/1.jpg" testimonial="John's experience was wonderful. The service was top-notch and exceeded expectations." /> <TestimonialCard name="Jane Smith" photo="https://randomuser.me/api/portraits/women/2.jpg" testimonial="Jane had a fantastic experience! Highly recommended for anyone looking for quality service." /> </div> </div> ); export default App;
Use this component everywhere, and update the styles easily from one place.
Compared to CSS Abstractions
When designing web interfaces, CSS alone isn't enough for complex components. You need both HTML and CSS to handle detailed UI elements effectively.
Consider a "Progress Tracker" as an example. Instead of styling each step individually with CSS, a component combines HTML and CSS for each step.
Example
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="flex justify-center items-center h-screen bg-gray-100"> <div class="w-full max-w-3xl px-4 py-6 bg-white rounded-lg shadow-md"> <div class="text-center mb-8 text-gray-800"> <p class="text mb-4 ml-4"> This tracker shows your progress through different stages: </p> <ul class="list-disc list-inside text-left text-gray-600"> <li><strong class="text-green-500">Completed:</strong> Finished steps </li> <li><strong class="text-yellow-500">Current:</strong> The active step </li> <li><strong class="text-gray-300">Upcoming:</strong> Future steps </li> </ul> </div> <div class="relative flex items-center"> <div class="absolute inset-0 flex items-center pointer-events-none"> <div class="flex-1 h-1 bg-green-500"></div> <div class="flex-1 h-1 bg-yellow-400"></div> <div class="flex-1 h-1 bg-gray-300"></div> <div class="flex-1 h-1 bg-gray-300"></div> </div> <!-- Steps --> <div class="flex-1 text-center relative z-10"> <div class="w-12 h-12 rounded-full bg-green-500 text-white flex items-center justify-center mx-auto mb-2 text-2xl"></div> <div class="text-sm">Step 1</div> </div> <div class="flex-1 text-center relative z-10"> <div class="w-12 h-12 rounded-full bg-yellow-500 text-white flex items-center justify-center mx-auto mb-2 text-2xl"></div> <div class="text-sm">Step 2</div> </div> <div class="flex-1 text-center relative z-10"> <div class="w-12 h-12 rounded-full bg-gray-200 text-white flex items-center justify-center mx-auto mb-2 text-2xl"></div> <div class="text-sm">Step 3</div> </div> <div class="flex-1 text-center relative z-10"> <div class="w-12 h-12 rounded-full bg-gray-200 text-white flex items-center justify-center mx-auto mb-3 text-2xl"></div> <div class="text-sm">Step 4</div> </div> <div class="absolute right-0 top-1/2 w-1/4 h-px bg-gray-300"></div> </div> </div> </body> </html>
Even if you use classes for styling, you'll end up duplicating HTML each time you use the component. While updating font size is simple, making more complex changes, like turning titles into links, is difficult with just CSS.
Components and template partials are better because they combine HTML and styles. This way, you can update font sizes or change all titles into links in one place.
Consider using a template partial or JavaScript component for a simpler solution.
Example
import React from 'react'; function Step({ status, number }) { const statusClasses = { completed: 'bg-green-500', current: 'bg-yellow-500', upcoming: 'bg-gray-200' }; return ( <div className="flex-1 text-center relative z-10"> <div className={`w-12 h-12 rounded-full ${statusClasses[status]} text-white flex items-center justify-center mx-auto mb-2 text-2xl`}> {status === 'completed' ? '' : status === 'current' ? '' : ''} </div> <div className="text-sm">Step {number}</div> </div> ); } function ProgressTracker() { return ( <div className="relative flex items-center"> <div className="absolute inset-0 flex items-center pointer-events-none"> <div className="flex-1 h-1 bg-green-500"></div> <div className="flex-1 h-1 bg-yellow-400"></div> <div className="flex-1 h-1 bg-gray-300"></div> <div className="flex-1 h-1 bg-gray-300"></div> </div> <Step status="completed" number={1} /> <Step status="current" number={2} /> <Step status="upcoming" number={3} /> <Step status="upcoming" number={4} /> <div className="absolute right-0 top-1/2 w-1/4 h-px bg-gray-300"></div> </div> ); } export default ProgressTracker;
With components and template partials, you only need utility classes because styles are handled in one place.
Extracting classes with Tailwind's @apply Directive
When designing web pages, using the same utility classes repeatedly can make your HTML messy and hard to manage.Tailwind CSS helps with this through the @apply directive.
What is @apply and When to Use It?
The @apply directive allows you to create custom CSS classes by applying a group of Tailwind utility classes. This keeps your HTML cleaner by moving repeated styles into your CSS files.
While template partials work well for complex components, @apply is great for frequently used styles. It helps keep your HTML clean and your styles consistent.
Before using @apply, you might add multiple utility classes directly in your HTML to style a card.
Example
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="p-4 bg-gray-200"> <div class="p-6 max-w-sm mx-auto bg-white rounded-lg shadow-md"> <h2 class="text-xl font-bold mb-2">Card Title</h2> <p class="text-gray-700 "> This is a card component styled with Tailwind utilities. </p> </div> </body> </html>
After Using @apply: Define a custom class for the card in your CSS, then use it in your HTML:
<div class="card"> <h2 class="card-title">Card Title</h2> <p class="card-content"> This is a card component styled with Tailwind utilities. </p> </div>
CSS with @apply
@tailwind base; @tailwind components; @tailwind utilities; @layer components { .card { @apply p-6 max-w-sm mx-auto bg-white rounded-lg shadow-md; } .card-title { @apply text-xl font-bold mb-2; } .card-content { @apply text-gray-700; } }
Using the @apply directive helps you keep your styling organized and your code cleaner.
Avoiding Premature Abstraction
Don't use @apply just to clean up your HTML. It might seem like a good idea, but it can create more problems:
- Naming Issues: Coming up with class names can be tiring.
- Multiple Edits: Overusing @apply means constantly switching between CSS and HTML.
- Style Changes: Changes to one class might unintentionally affect other parts of your site.
- Larger CSS Files: Many custom classes can increase your CSS file size and impact performance.
Use @apply for small, reusable items like buttons, or use components in a framework like React for better management.