All topics
Frontend · Learning hub

Tailwindcss notes for developers

Master Tailwindcss with a curated set of 3 developer notes — core concepts, patterns, and interview prep. Maintained by the DevRecall team.

Save this stack to your DevRecallMore Frontend notes
Tailwindcss

Utility Classes & Layout

Utility Classes & Layout Spacing <!-- Padding: p-{n}, px-{n}, py-{n}, pt/pr/pb/pl-{n} --> <div class="p-4"> <!-- padding: 16px --> <div class="px-6 py-3"> <!--

Utility Classes & Layout

Spacing

<!-- Padding: p-{n}, px-{n}, py-{n}, pt/pr/pb/pl-{n} -->
<div class="p-4">           <!-- padding: 16px -->
<div class="px-6 py-3">     <!-- padding-x: 24px, padding-y: 12px -->
<div class="pt-2 pb-8">     <!-- top: 8px, bottom: 32px -->

<!-- Margin: m-{n}, mx-{n}, my-{n}, mt/mr/mb/ml-{n} -->
<div class="m-4">            <!-- margin: 16px -->
<div class="mx-auto">        <!-- center horizontally -->
<div class="mt-0 mb-4">      <!-- top: 0, bottom: 16px -->
<div class="-mt-4">          <!-- negative margin: -16px -->

<!-- Space between children -->
<div class="flex gap-4">     <!-- flex gap: 16px -->
<div class="space-x-4">      <!-- margin-left on each child -->
<div class="space-y-6">      <!-- margin-top on each child -->

<!-- Scale: 0=0, 1=4px, 2=8px, 3=12px, 4=16px, 5=20px, 6=24px,
           8=32px, 10=40px, 12=48px, 16=64px, 20=80px, 24=96px -->

Flexbox

<!-- Flex container -->
<div class="flex">                    <!-- display: flex -->
<div class="inline-flex">            <!-- display: inline-flex -->
<div class="flex flex-col">          <!-- column direction -->
<div class="flex flex-row-reverse"> <!-- reverse row -->
<div class="flex flex-wrap">         <!-- allow wrapping -->
<div class="flex flex-nowrap">       <!-- no wrap -->

<!-- Alignment -->
<div class="flex items-center">      <!-- align-items: center -->
<div class="flex items-start">       <!-- flex-start -->
<div class="flex items-stretch">     <!-- stretch (default) -->
<div class="flex justify-center">    <!-- justify-content: center -->
<div class="flex justify-between">   <!-- space-between -->
<div class="flex justify-around">    <!-- space-around -->
<div class="flex justify-evenly">    <!-- space-evenly -->

<!-- Common centering pattern -->
<div class="flex items-center justify-center">

<!-- Flex children -->
<div class="flex-1">                 <!-- flex: 1 1 0% (grow and shrink) -->
<div class="flex-auto">             <!-- flex: 1 1 auto -->
<div class="flex-none">             <!-- flex: none -->
<div class="grow">                   <!-- flex-grow: 1 -->
<div class="shrink-0">              <!-- flex-shrink: 0 -->
<div class="basis-1/2">             <!-- flex-basis: 50% -->
<div class="self-end">              <!-- align-self: flex-end -->
<div class="order-first">           <!-- order: -9999 -->

Grid

<!-- Grid container -->
<div class="grid grid-cols-3 gap-4">   <!-- 3 equal columns -->
<div class="grid grid-cols-12 gap-6">  <!-- 12-column layout -->
<div class="grid grid-cols-[1fr_2fr_1fr] gap-4">  <!-- custom track sizes -->

<!-- Responsive grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">

<!-- Grid children -->
<div class="col-span-2">              <!-- span 2 columns -->
<div class="col-span-full">           <!-- span all columns -->
<div class="col-start-2 col-end-4">  <!-- from col 2 to 4 -->
<div class="row-span-2">             <!-- span 2 rows -->

<!-- Auto grid -->
<div class="grid grid-cols-[repeat(auto-fill,minmax(250px,1fr))] gap-4">

Typography & Colors

<!-- Font size: text-xs(12) sm(14) base(16) lg(18) xl(20) 2xl(24) 3xl(30) 4xl(36) -->
<h1 class="text-4xl font-bold tracking-tight">

<!-- Font weight: thin(100) light(300) normal(400) medium(500) semibold(600) bold(700) -->
<p class="font-semibold">

<!-- Line height: leading-none(1) tight(1.25) snug(1.375) normal(1.5) relaxed(1.625) -->
<p class="leading-relaxed">

<!-- Letter spacing: tracking-tighter/tight/normal/wide/wider/widest -->
<h2 class="tracking-wide">

<!-- Text align, decoration, transform -->
<p class="text-center">
<p class="text-right">
<a class="underline decoration-blue-500">
<p class="uppercase tracking-widest">
<p class="truncate">                   <!-- overflow ellipsis, single line -->
<p class="line-clamp-3">              <!-- clamp to 3 lines -->

<!-- Colors: {property}-{color}-{shade} -->
<p class="text-gray-700 dark:text-gray-300">
<div class="bg-blue-500 hover:bg-blue-600">
<div class="border border-gray-200">
<svg class="text-red-500 fill-current">

<!-- Opacity: text-blue-500/75  bg-black/50 -->
<div class="bg-blue-500/10 text-blue-700/80">

Sizing & Positioning

<!-- Width / Height -->
<div class="w-full">      <!-- 100% -->
<div class="w-1/2">       <!-- 50% -->
<div class="w-64">        <!-- 256px (16rem) -->
<div class="w-fit">       <!-- fit-content -->
<div class="w-screen">    <!-- 100vw -->
<div class="min-w-0">     <!-- min-width: 0 (fix flex overflow) -->
<div class="max-w-sm">    <!-- max-width: 24rem (384px) -->
<div class="max-w-7xl mx-auto">  <!-- centered container -->
<div class="h-screen">    <!-- 100vh -->
<div class="min-h-screen"> <!-- fill page -->
<div class="aspect-video"> <!-- 16/9 -->
<div class="aspect-square"> <!-- 1/1 -->

<!-- Position -->
<div class="relative">
<div class="absolute inset-0">       <!-- top/right/bottom/left: 0 -->
<div class="absolute top-4 right-4"> <!-- positioned -->
<div class="fixed bottom-4 right-4"> <!-- fixed to viewport -->
<div class="sticky top-0 z-50">      <!-- sticky header -->

<!-- Display -->
<div class="hidden">                 <!-- display: none -->
<div class="block">
<span class="inline-block">
<div class="overflow-hidden">
<div class="overflow-auto">
<div class="overflow-x-auto">
Tailwindcss

Responsive, Dark Mode & Config

Responsive, Dark Mode & Config Responsive Breakpoints sm — 640px+ md — 768px+ lg — 1024px+ xl — 1280px+ 2xl — 1536px+ <!-- Mobile-first: base = mobile, add brea

Responsive, Dark Mode & Config

Responsive Breakpoints

  • sm — 640px+

  • md — 768px+

  • lg — 1024px+

  • xl — 1280px+

  • 2xl — 1536px+

<!-- Mobile-first: base = mobile, add breakpoints for larger screens -->
<div class="text-sm md:text-base lg:text-lg">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<div class="hidden md:block">         <!-- hidden on mobile, visible md+ -->
<div class="block md:hidden">         <!-- visible on mobile, hidden md+ -->
<div class="p-4 md:p-8 lg:p-12">

<!-- Max-breakpoint modifier (Tailwind v3.2+) -->
<div class="md:max-lg:hidden">        <!-- hidden between md and lg -->

<!-- Container with responsive padding -->
<div class="container mx-auto px-4 sm:px-6 lg:px-8">

State Variants

<!-- Hover / Focus / Active -->
<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">

<!-- Group hover (parent hover affects children) -->
<div class="group">
  <div class="bg-white group-hover:bg-blue-500">  <!-- changes on parent hover -->
  <p class="text-gray-600 group-hover:text-white">

<!-- Peer (sibling state) -->
<input class="peer" type="checkbox" />
<label class="peer-checked:text-blue-500">

<!-- Disabled -->
<button class="disabled:opacity-50 disabled:cursor-not-allowed">

<!-- Form states -->
<input class="border border-gray-300 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 invalid:border-red-500">

<!-- First/last child -->
<li class="py-2 border-b last:border-b-0">
<li class="py-2 border-t first:border-t-0">

<!-- Odd/even rows -->
<tr class="odd:bg-white even:bg-gray-50">

Dark Mode

<!-- Dark mode classes -->
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
<div class="border-gray-200 dark:border-gray-700">
<button class="bg-blue-500 dark:bg-blue-600 hover:bg-blue-600 dark:hover:bg-blue-700">
// tailwind.config.js — class-based dark mode (manual toggle)
module.exports = {
  darkMode: 'class',   // toggle by adding 'dark' class to <html>
  // darkMode: 'media', // follows OS preference
}

// Toggle dark mode
document.documentElement.classList.toggle('dark');

Customization (tailwind.config.js)

// tailwind.config.ts
import type { Config } from 'tailwindcss';

export default {
  content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
  darkMode: 'class',
  theme: {
    // Override — replaces defaults entirely
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
    },
    extend: {
      // Extend — adds to defaults
      colors: {
        brand: {
          50: '#eff6ff',
          500: '#3b82f6',
          900: '#1e3a8a',
        },
      },
      spacing: {
        '18': '4.5rem',
        '128': '32rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
      animation: {
        'fade-in': 'fadeIn 0.2s ease-in-out',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
      },
      screens: {
        'xs': '475px',  // add custom breakpoint
      },
    },
  },
  plugins: [
    require('@tailwindcss/typography'),   // prose classes
    require('@tailwindcss/forms'),         // form reset
    require('@tailwindcss/line-clamp'),    // line-clamp (v3 built-in)
  ],
} satisfies Config;

Common Patterns

<!-- Card -->
<div class="rounded-xl border border-gray-200 bg-white p-6 shadow-sm dark:border-gray-700 dark:bg-gray-800">

<!-- Badge -->
<span class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800">

<!-- Button -->
<button class="inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 disabled:opacity-50">

<!-- Input -->
<input class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">

<!-- Divider -->
<div class="relative">
  <div class="absolute inset-0 flex items-center"><span class="w-full border-t"></span></div>
  <div class="relative flex justify-center text-sm"><span class="bg-white px-2 text-gray-500">or</span></div>
</div>
Tailwindcss

Interview Questions

Tailwind CSS Interview Questions Q: What is utility-first CSS and what are its benefits? Utility-first CSS uses small, single-purpose classes (like flex, mt-4,

Tailwind CSS Interview Questions

Q: What is utility-first CSS and what are its benefits?

Utility-first CSS uses small, single-purpose classes (like flex, mt-4, text-blue-500) directly in HTML instead of writing custom CSS classes. Benefits: no naming bikeshedding, styles colocated with markup, no dead CSS (PurgeCSS removes unused), consistent design tokens, faster iteration. Downsides: verbose markup, need to extract reusable patterns with @apply or components.

Q: How does Tailwind minimize bundle size?

Tailwind scans your content files (configured in content array) and generates only the CSS classes actually used. Unused utilities are purged. The final CSS bundle is typically 5-20KB gzipped — much smaller than full CSS frameworks. In development, Tailwind generates the full stylesheet for fast iteration.

Q: What is @apply and when should you use it?

@apply lets you compose utility classes into a custom CSS class. Use it sparingly for truly reusable UI components (buttons, inputs) where you'd otherwise repeat the same 15 classes everywhere. Avoid over-using it — it defeats the purpose of utility-first and makes it harder to see styles in the markup.

Q: What is the difference between sm:hidden and hidden sm:block?

Tailwind is mobile-first. Breakpoint prefixes apply at that size and up. sm:hidden means "hidden from 640px and up" (visible on mobile). hidden sm:block means "hidden by default (mobile), visible from 640px up". These are opposite patterns for responsive show/hide.

Q: How do you use Tailwind with a component library like React?

Use the cn() or clsx() utility to conditionally combine classes. For component variants, libraries like cva (class-variance-authority) let you define variant-based class maps. Always pass className props to allow customization. Use tailwind-merge (twMerge) to properly merge conflicting Tailwind classes (e.g., merging p-4 with p-8 correctly results in only p-8).

Keep your Tailwindcss knowledge sharp.

Save this stack to your personal DevRecall — add your own notes, track what you're learning, and share what you know with the community.

Get started — free forever