Tailwind CSS Basics
Tailwind CSS basics for React: utility-first styling, spacing, flex/grid, hover/focus, responsive and dark variants, conditional classes, and reusable component patterns.
Tailwind CSS Basics
Tailwind CSS is a utility-first CSS framework that lets you style components by combining small, reusable utility classes.
Instead of creating a separate CSS class:
.button {background-color: #2563eb;color: white;padding: 10px 20px;border-radius: 6px;}
<button className="button">Save</button>
Tailwind expresses those styles directly in JSX:
<button className="bg-blue-600 text-white px-5 py-2 rounded-md">Save</button>
Build your UI by composing small utility classes instead of writing custom CSS for every component.
Learning Objectives
- What utility-first CSS is and how Tailwind class names work
- Typography, color, spacing, flex, and grid utilities
- Variants:
hover:,focus:, responsive, anddark: - Conditional classes, component variants, and arbitrary values
- How Tailwind compares to regular CSS and CSS Modules
- Best practices, accessibility, and interview questions
What Is Tailwind CSS?
Tailwind provides utility classes for common CSS properties:
text-blue-600 bg-gray-100 p-4 px-6 py-2 mt-4rounded-lg shadow-md flex grid items-center justify-between
<div className="p-4"> {/* padding: 1rem */}<div className="text-center"> {/* text-align: center */}
Utility-First CSS
Traditional: Component → Create CSS class → Write CSS → Apply classTailwind: Component → Compose utility classes → UI
<div className="bg-white p-6 rounded-lg shadow-md">Card content</div>
bg-white → backgroundp-6 → paddingrounded-lg → border radiusshadow-md → shadow
Installing Tailwind CSS
Installation depends on Tailwind version and build tooling. Follow the official install guide for your version rather than copying old tutorial config. Once configured, use utilities in JSX:
function App() {return (<h1 className="text-3xl font-bold">Hello React</h1>);}
Tailwind Classes in React
React uses className, not HTML class:
<h1 className="text-4xl font-bold">Welcome</h1>
Understanding Tailwind Class Names
Names follow a predictable pattern:
text-blue-600 → text (property) + blue (color) + 600 (shade)px-4 → horizontal paddingpy-2 → vertical paddingmt-4 → margin-toprounded-lg → border radius
Text Styling
<h1 className="text-4xl font-bold">React Course</h1><p className="text-gray-600">Learn React step by step.</p><p className="text-blue-600">Information</p><p className="text-green-600">Success</p><p className="text-red-600">Error</p><h2 className="text-center">Centered Heading</h2>{/* also: text-left, text-right */}
Background Colors
<div className="bg-blue-600">Content</div>{/* bg-white bg-black bg-gray-100 bg-gray-900bg-blue-500 bg-green-500 bg-red-500 */}<div className="bg-blue-600 text-white">Blue panel</div>
Padding
p-4 → all sidespt-4 pr-4 pb-4 pl-4 → directionspx-4 → horizontalpy-4 → vertical
<button className="px-6 py-3">Save</button>
Margin
m-4 mt-4 mr-4 mb-4 ml-4 mx-4 my-4
<div className="mt-6">Next section</div>
Spacing Between Elements
<div className="flex gap-4"><button>Save</button><button>Cancel</button></div><div className="grid gap-6">...</div>
Prefer gap-* over manually adding margins to every child.
Flexbox
flex flex-row flex-colitems-center items-start items-endjustify-center justify-between justify-start justify-end
<nav className="flex items-center justify-between"><div>Logo</div><div>Menu</div></nav>
Flex Column
<div className="flex flex-col gap-4"><div>First</div><div>Second</div><div>Third</div></div>
Grid
<div className="grid grid-cols-3 gap-6"><div>Card 1</div><div>Card 2</div><div>Card 3</div></div>
Width and Height
w-full w-screen w-1/2 w-64h-full h-screen h-64
<div className="w-64 h-32">Box</div><div className="w-full">Full width</div>
Borders
<div className="border border-gray-200">Card</div>{/* border border-2 border-4 */}
Border Radius
rounded rounded-sm rounded-md rounded-lg rounded-xl rounded-full
<imgclassName="w-12 h-12 rounded-full"src="/avatar.jpg"alt="User"/>
Shadows
<div className="bg-white rounded-lg shadow-md p-6">Course Card</div>{/* shadow-sm shadow shadow-md shadow-lg shadow-xl */}
Hover States
<button className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded">Save</button>
hover:bg-blue-700 → When hovered, use bg-blue-700
Focus States
<inputclassName="border border-gray-300 focus:border-blue-500"placeholder="Enter your name"/><inputclassName="border border-gray-300 focus:outline-none focus:ring-2"placeholder="Email"/>
Keep focus styling visible for accessibility.
Responsive Design
<div className="text-center md:text-left">Responsive text</div>
Small screens → text-centerMedium and up → text-left
Responsive Grid
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"><Card /><Card /><Card /><Card /></div>
Mobile → 1 columnTablet → 2 columnsDesktop → 3 columns
Responsive Visibility
<div className="block md:hidden">Mobile Menu</div><div className="hidden md:block">Desktop Menu</div>
Dark Mode
<div className="bg-white text-black dark:bg-gray-900 dark:text-white">Content</div>
Exact dark-mode setup depends on Tailwind version and project config.
Conditional Tailwind Classes
function Button({ active }) {return (<buttonclassName={active? "bg-blue-600 text-white": "bg-gray-200 text-gray-800"}>Button</button>);}function Button({ active, disabled }) {const classes = ["px-4","py-2","rounded-md",active ? "bg-blue-600 text-white" : "bg-gray-200",disabled && "opacity-50 cursor-not-allowed"].filter(Boolean).join(" ");return <button className={classes}>Save</button>;}
Larger apps often use helpers like clsx.
Building a Tailwind Button
function Button({ children, variant = "primary" }) {const baseClasses ="px-4 py-2 rounded-md font-medium transition";const variants = {primary: "bg-blue-600 text-white hover:bg-blue-700",secondary: "bg-gray-200 text-gray-900 hover:bg-gray-300",danger: "bg-red-600 text-white hover:bg-red-700"};return (<button className={`${baseClasses} ${variants[variant]}`}>{children}</button>);}<Button>Save</Button><Button variant="secondary">Cancel</Button><Button variant="danger">Delete</Button>
Component props → Choose variant → Choose Tailwind classes → Render UI
Building a Card
function CourseCard() {return (<article className="bg-white border border-gray-200 rounded-xl shadow-sm p-6"><h2 className="text-xl font-bold text-gray-900">React Fundamentals</h2><p className="mt-2 text-gray-600">Learn the fundamentals of React and component-based development.</p><button className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">Start Learning</button></article>);}
No separate CourseCard.css — styling lives in utility classes.
Tailwind and Component Reusability
React → Components → Props → Tailwind utilities → Styled UI
function Card({ title, description }) {return (<article className="rounded-lg border p-6 shadow-sm"><h2 className="text-xl font-semibold">{title}</h2><p className="mt-2 text-gray-600">{description}</p></article>);}<Card title="React" description="Learn React fundamentals." /><Card title="TypeScript" description="Learn TypeScript for frontend." />
Tailwind and Component Variants
function Badge({ status }) {const styles = {success: "bg-green-100 text-green-800",warning: "bg-yellow-100 text-yellow-800",error: "bg-red-100 text-red-800"};return (<spanclassName={`px-3 py-1 rounded-full text-sm ${styles[status]}`}>{status}</span>);}<Badge status="success" /><Badge status="warning" /><Badge status="error" />
Arbitrary Values
<div className="w-[375px]">Content</div><div className="bg-[#123456]">Content</div><div className="mt-[37px]">Content</div>
Useful for genuine custom needs — avoid using them everywhere. Repeated values belong in the design system.
Tailwind Transitions
<button className="bg-blue-600 hover:bg-blue-700 transition">Save</button><button className="transition duration-300">Save</button><div className="transition-transform hover:scale-105">Card</div>
Tailwind Animations
<div className="animate-spin">Loading...</div>
Built-in animations depend on version/config. Extend Tailwind or use CSS for custom animations when needed.
Tailwind and Accessibility
Tailwind does not make UI accessible automatically. Still consider semantic HTML, keyboard nav, focus, contrast, labels, button semantics, alt text, and screen readers.
<button className="px-4 py-2 bg-blue-600 text-white rounded-md focus:ring-2">Save</button>
Tailwind vs Regular CSS
| Feature | Regular CSS | Tailwind |
|---|---|---|
| Approach | Custom CSS | Utility classes |
| CSS files | Common | Often fewer |
| Responsive | Media queries | Responsive variants |
| Hover | Pseudo-classes | hover: variants |
| Reusability | Classes/components | Components + utilities |
Tailwind vs CSS Modules
CSS Modules: Create CSS → Reference class (styles.button)Tailwind: Compose utilities → Style directly in JSX
Both can be excellent — choose based on architecture and team preference.
Advantages of Tailwind CSS
- Fast UI development — style without jumping between JSX and CSS files
- Consistent design — shared spacing, type, and color scales
- Responsive design — concise breakpoint variants
- Component-friendly — fits React architecture
- Less naming overhead — fewer invented class names
Potential Disadvantages
- Long class lists can be hard to read
- You must learn utility naming conventions
- Repeated combinations need component extraction
- JSX can become visually noisy
Combine Tailwind with good component design — do not abandon the framework over noise alone.
Best Practices
- Build reusable components for repeated utility combinations
- Prefer semantic names (
Button,Card,Badge) - Use responsive utilities only when layout must change
- Prefer scale utilities (
p-6) over arbitrary values unless required - Keep accessibility in mind
- Extract repeated patterns into components or a design system
Common Mistakes
Mistake 1 — class instead of className
// Incorrect<button class="bg-blue-600">// Correct<button className="bg-blue-600">
Mistake 2 — Treating Tailwind as a component library
Tailwind styles — you still build Navbar, Modal, DataTable, Dashboard yourself (or use a component library).
Mistake 3 — Huge repeated class lists
Extract a reusable React component.
Mistake 4 — Ignoring responsive design
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
Mistake 5 — Ignoring focus styles
Do not style only hover — keyboard users need visible focus.
Tailwind Mental Model
React Component│▼className string│┌─────────────┼─────────────┐▼ ▼ ▼Layout Spacing Typography│ │ │flex p-4 text-xlgrid gap-4 font-bold│ │ │└─────────────┼─────────────┘▼Styled UI
Ask: "Which utilities describe the styling this component needs?" rather than inventing a new CSS class name every time.
A Complete Example
function CourseCard({ title, description, level }) {return (<articleclassName="rounded-xl border border-gray-200 bg-white p-6shadow-sm transition hover:shadow-md"><div className="flex items-center justify-between"><h2 className="text-xl font-bold text-gray-900">{title}</h2><span className="rounded-full bg-blue-100 px-3 py-1 text-sm text-blue-700">{level}</span></div><p className="mt-3 text-gray-600">{description}</p><buttonclassName="mt-5 rounded-md bg-blue-600 px-4 py-2font-medium text-white transitionhover:bg-blue-700 focus:ring-2">Start Course</button></article>);}<CourseCardtitle="React Fundamentals"description="Learn the fundamentals of React."level="Beginner"/>
Practice Exercises
- Button — primary / secondary / danger variants
- Profile card — avatar, name, title, description, Follow
- Responsive grid — 6 cards; 1 / 2 / 3 columns
- Navbar — Logo, Home, Courses, About, Contact with Flexbox
- Dark mode card — use
dark:utilities
Interview Questions
1. What is Tailwind CSS?
A utility-first CSS framework for composing UI with predefined utility classes.
2. What does utility-first mean?
Styling by combining small classes, each generally representing a specific CSS property or behavior.
3. How do you use Tailwind in React?
<div className="p-4 bg-white rounded-lg">
4. Responsive design?
<div className="text-center md:text-left">
5. Hover styles?
<button className="hover:bg-blue-700">
6. Conditional classes?
Ternaries, arrays + join, or helpers like clsx.
7. Does Tailwind replace React components?
No — Tailwind styles; React owns structure, state, and behavior.
8. Automatic accessibility?
No — accessibility remains the developer's responsibility.
9. What is an arbitrary value?
<div className="w-[375px]">
10. Tailwind or CSS Modules?
Neither is universally better — depends on architecture and team preference.
Quick Cheat Sheet
| Category | Examples |
|---|---|
| Text | text-xl text-center font-bold text-gray-600 |
| Background | bg-white bg-blue-600 bg-gray-100 |
| Spacing | p-4 px-6 py-2 mt-4 gap-4 |
| Layout | flex grid items-center justify-between grid-cols-3 |
| Size | w-full w-1/2 h-screen |
| Border | border border-gray-200 rounded-lg rounded-full |
| Shadow | shadow shadow-md shadow-lg |
| Interaction | hover:bg-blue-700 focus:ring-2 transition |
| Responsive | md:flex md:grid-cols-2 lg:grid-cols-3 |
| Dark mode | dark:bg-gray-900 dark:text-white |
| Arbitrary | w-[375px] mt-[37px] |
Key Takeaway
Traditional: Component → CSS file → Custom class → CSS rulesTailwind: Component → Utility classes → Styled UI
<button className="rounded-md bg-blue-600 px-5 py-2 font-medium text-white hover:bg-blue-700">Save</button>
React + Components + Props + Tailwind utilities↓Reusable, consistent UI
Next: organize utilities into reusable UI patterns and scalable component styling systems.