Menu

Tailwind CSS Display

The display property defines how elements are rendered within the document flow— whether as block-level elements, inline elements, flex containers, or other layout types. It plays a crucial role in shaping the structure and behavior of your design.

Tailwind CSS makes toggling between these display styles effortless with its intuitive utility classes. In this guide, we’ll explore how to effectively use Tailwind’s display utilities to build responsive, well-structured layouts.

ClassPropertiesExample
blockdisplay: block;<div className="block"></div>
inline-blockdisplay: inline-block;<div className="inline-block"></div>
inlinedisplay: inline;<div className="inline"></div>
flexdisplay: flex;<div className="flex"></div>
inline-flexdisplay: inline-flex;<div className="inline-flex"></div>
tabledisplay: table;<div className="table"></div>
inline-tabledisplay: inline-table;<div className="inline-table"></div>
table-captiondisplay: table-caption;<div className="table-caption"></div>
table-celldisplay: table-cell;<div className="table-cell"></div>
table-columndisplay: table-column;<div className="table-column"></div>
table-column-groupdisplay: table-column-group;<div className="table-column-group"></div>
table-footer-groupdisplay: table-footer-group;<div className="table-footer-group"></div>
table-header-groupdisplay: table-header-group;<div className="table-header-group"></div>
table-row-groupdisplay: table-row-group;<div className="table-row-group"></div>
table-rowdisplay: table-row;<div className="table-row"></div>
flow-rootdisplay: flow-root;<div className="flow-root"></div>
griddisplay: grid;<div className="grid"></div>
inline-griddisplay: inline-grid;<div className="inline-grid"></div>
contentsdisplay: contents;<div className="contents"></div>
list-itemdisplay: list-item;<div className="list-item"></div>
hiddendisplay: none;<div className="hidden"></div>

Overview of Display

Block and Inline Elements

Block elements spans the full line width by default. Items typically stack vertically, each occupying its own line. Conversely, inline elements render side by side with other inline elements without a line break. If the element is inline-block, it wraps normally around other inline elements but can have its own height, width, margin, and padding values.

Tailwind provides block, inline-block, and inline utilities for the above display properties.

This is a live editor. Play around with it!
export default function BlockInlineShowcase() {
  return (
    <div className="bg-gray-200 p-4 h-screen w-screen">
      {/* Parent container */}
      <p className="mb-4">
        Following are the examples of "Inline" vs "Inline Block", and "Block":
        {/* CSS: display: block */}
        <span className="block bg-red-200 mt-4">I'm a block element.</span>
        {/* CSS: display: inline-block */}
        <span className="inline-block bg-green-200 h-10">
          I am an inline-block element.
        </span>
        {/* CSS: display: inline */}
        <span className="inline bg-yellow-200 px-2 h-20 ml-2">
          I am an inline element.
        </span>
      </p>
    </div>
  );
}

Flow Root Element

Flow-root elements create a new block formatting context, which ensures that floated elements are contained within their parent. This prevents layout issues, such as content overlapping or collapsing, by isolating the element's layout from the rest of the page. In Tailwind CSS, you can use the flow-root utility class to apply display: flow-root to an element.

This is a live editor. Play around with it!
export default function FlowRootDemo() {
  return (
    <div className="w-full max-w-sm bg-gray-100 p-4 space-y-4">
      {/* Without flow-root */}
      <h3 className="font-medium text-lg mb-2">Without flow-root:</h3>
      <div className="bg-red-100 p-4">
        <img
          src="https://images.unsplash.com/photo-1508108712903-49b7ef9b1df8"
          alt="Floated element"
          className="float-left w-16 h-16 mr-4"
        />
        <p className="text-sm">Short text.</p>
      </div>
      <p className="bg-yellow-100 p-4 text-sm">
        ⬅️ Notice how this yellow box is affected by the float above! The text starts after the image instead of at the left edge.
      </p>

      {/* With flow-root */}
      <h3 className="font-medium text-lg mb-2">With flow-root:</h3>
      <div className="flow-root bg-green-100 p-4">
        <img
          src="https://images.unsplash.com/photo-1508108712903-49b7ef9b1df8"
          alt="Floated element"
          className="float-left w-16 h-16 mr-4"
        />
        <p className="text-sm">Short text.</p>
      </div>
      <p className="bg-blue-100 p-4 text-sm">
        ✅ This blue box starts at the left edge because flow-root contains the float above properly.
      </p>
    </div>
  );
}

Flex Element

When an element has flex utility, it becomes a flex container in Tailwind, enabling flex item alignment, spacing, and consistent distribution of space along a single row (or a column when flex-direction changes). It’s one of the most common display modes for modern responsive layouts because it allows items to expand or shrink dynamically to fill available space.

This is a live editor. Play around with it!
export default function FlexLayout() {
  return (
    <div className="bg-gray-200 p-4 h-screen w-screen">
      <div className="flex bg-red-100">
        {/* CSS: display: flex */}
        <div className="p-4 border border-red-500 m-2">
          Item One
        </div>
        <div className="p-4 border border-red-500 m-2">
          Item Two
        </div>
        <div className="p-4 border border-red-500 m-2">
          Item Three
        </div>
      </div>
      <p className="mt-4">
        The *flex* class can be combined with justify and align utilities to
        achieve advanced sizing or alignment goals.
      </p>
    </div>
  );
}

Inline Flex Element

Inline flex merges the benefits of flex with the natural behavior of inline elements. By applying display: inline-flex, your flex container can remain on the same text line or shared line with other inline elements, if space permits, instead of starting on a new line.

This is a live editor. Play around with it!
export default function InlineFlexVsSpan() {
  return (
    <div className="w-full max-w-sm p-4 space-y-6 bg-gray-50">
      {/* Regular span example */}
      <div className="mb-4">
        <h3 className="font-semibold mb-2">Regular span:</h3>
        <p>
          Text with a
          <span className="bg-red-50 p-2">
            <span className="w-4 h-4 bg-red-200"></span>
            <span>Can't vertically align</span>
            <span className="bg-red-200"></span>
          </span>
          in text flow.
        </p>
      </div>

      {/* Inline-flex example */}
      <div className="mb-4">
        <h3 className="font-semibold mb-2">Inline-flex:</h3>
        <p>
          Text with an
          <span className="inline-flex items-center gap-2 bg-blue-50 p-2 min-w-40">
            <span className="w-4 h-4 bg-blue-200 rounded-full"></span>
            <span>Centered content</span>
            <span className="bg-blue-200 px-2 rounded"></span>
          </span>
          in text flow.
        </p>
      </div>

      {/* Multiple inline-flex with alignment */}
      <div>
        <h3 className="font-semibold mb-2">Complex inline-flex alignment:</h3>
        <p>
          You can mix text with
          <span className="inline-flex flex-col gap-2 bg-green-50 px-3 py-1">
            <span className="w-3 h-3 bg-green-400 rounded-full"></span>
            <span>vertically stacked</span>
            <span className="text-xs bg-green-200 px-2 rounded">99+</span>
          </span>
          and even have
          <span className="inline-flex items-center justify-between gap-2 bg-purple-50 px-3 py-1 w-48">
            <span className="w-3 h-3 bg-purple-400 rounded-full"></span>
            <span>space-between</span>
            <span className="text-xs"></span>
          </span>
          layouts inline.
        </p>
      </div>
    </div>
  );
}

Grid Element

Grid is a powerful layout system that enables two-dimensional structuring—both rows and columns simultaneously. Tailwind’s grid, grid-cols-, grid-rows-, and other classes let you produce flexible or fixed grid templates. In Tailwind, the grid utility maps the container to the display: grid property.

This is a live editor. Play around with it!
export default function GridLayout() {
  return (
    <div className="bg-gray-200 p-4 h-screen w-screen">
      <div className="grid grid-cols-3 gap-4 bg-green-50 p-4">
        {/* CSS: display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); */}
        <div className="border border-green-500 p-4">Box 1</div>
        <div className="border border-green-500 p-4">Box 2</div>
        <div className="border border-green-500 p-4">Box 3</div>
        <div className="border border-green-500 p-4">Box 4</div>
        <div className="border border-green-500 p-4">Box 5</div>
        <div className="border border-green-500 p-4">Box 6</div>
      </div>
      <p className="mt-4">
        This grid automatically arranges each item into a three-column structure. 
        You can adjust *gap-4*, *grid-cols-3*, or other utilities to fit your needs.
      </p>
    </div>
  );
}

Inline Grid Element

An inline grid is similar to the inline flex concept. By using display: inline-grid, you can place the grid container in an inline formatting context, allowing it to reside alongside inline or text elements. It behaves similarly to a block-level grid, except it does not force a line break before and after.

This is a live editor. Play around with it!
export default function InlineGridLayout() {
  return (
    <div className="bg-gray-200 p-4 h-screen w-screen">
      <p className="mb-2">
        Below is an inline grid with two columns inside a line of text:
      </p>
      <span className="inline-grid grid-cols-2 gap-2 bg-pink-100 p-2">
        {/* CSS: display: inline-grid; grid-template-columns: repeat(2, minmax(0, 1fr)); */}
        <span className="border border-pink-500 px-2">Item A</span>
        <span className="border border-pink-500 px-2">Item B</span>
        <span className="border border-pink-500 px-2">Item C</span>
        <span className="border border-pink-500 px-2">Item D</span>
      </span>
      <span className="ml-2">
        More text on the inline level.
      </span>
    </div>
  );
}

Contents Element

Tailwind’s contents utility sets display: contents, which makes child elements appear like direct children of the grandparent. The contents can be used to remove an intermediate wrapper from the layout perspective, although it does not remove the actual element from the DOM tree. This approach can be advantageous for complex grid or flex-based child elements where the parent container must be visually bypassed.

This is a live editor. Play around with it!
export default function ContentsDisplay() {
  return (
    <div className="w-full max-w-sm bg-gray-50 p-4 space-y-4 h-screen">
      {/* Without display: contents */}
      <div>
        <h3 className="font-medium mb-2">Without display: contents:</h3>
        <div className="grid grid-cols-2 gap-2 bg-blue-50 p-2">
          <div className="bg-white p-2 border border-blue-200">
            <p className="bg-blue-100 p-2 text-sm">Child 1</p>
            <p className="bg-blue-100 p-2 text-sm mt-2">Child 2</p>
          </div>
          <div className="bg-white p-2 border border-blue-200">
            <p className="text-sm">Takes one column</p>
          </div>
        </div>
        <p className="text-xs mt-2 text-gray-600">
          ⬆️ The wrapper div takes up one grid column
        </p>
      </div>

      {/* With display: contents */}
      <div>
        <h3 className="font-medium mb-2">With display: contents:</h3>
        <div className="grid grid-cols-2 gap-2 bg-green-50 p-2">
          <div className="contents">
            <p className="bg-white p-2 border border-green-200 text-sm">Child 1</p>
            <p className="bg-white p-2 border border-green-200 text-sm">Child 2</p>
          </div>
          <div className="bg-white p-2 border border-green-200">
            <p className="text-sm">Doesn't take one column</p>
          </div>
        </div>
        <p className="text-xs mt-2 text-gray-600">
          ⬆️ Each child participates in the grid layout directly
        </p>
      </div>
    </div>
  );
}

Table Element

A table display sets an element’s display to behave like a <table> in HTML. You can pair it with table-related utilities in Tailwind (e.g., table-row, table-cell) to replicate a tabular layout. Although using Flex or Grid is often more common, table-based displays can be useful for purely tabular data or older layout patterns.

This is a live editor. Play around with it!
export default function TableLayout() {
  return (
    <div className="bg-gray-200 p-4 h-screen w-screen">
      <div className="table border-collapse border border-gray-800">
        {/* CSS: display: table; */}
        <div className="table-row bg-blue-50">
          <div className="table-cell border border-gray-400 p-2">Row 1, Cell 1</div>
          <div className="table-cell border border-gray-400 p-2">Row 1, Cell 2</div>
        </div>
        <div className="table-row bg-white">
          <div className="table-cell border border-gray-400 p-2">Row 2, Cell 1</div>
          <div className="table-cell border border-gray-400 p-2">Row 2, Cell 2</div>
        </div>
      </div>
    </div>
  );
}

Hidden Element

Hidden in Tailwind equates to display: none, effectively removing an element from the render flow. This differs from other presence-based classes like invisible (which preserves layout space). When an element is set to hidden, it is entirely absent visually, and it does not affect the positioning of siblings.

Use hidden for toggling entire content regions off, helpful in scenarios like conditionally rendering certain elements.

This is a live editor. Play around with it!
export default function HidingElements() {
  return (
    <div className="bg-gray-200 p-4 h-screen w-screen">
      <div className="p-2 bg-gray-300 mb-2">
        <p>Visible container</p>
      </div>
      <div className="hidden p-2 bg-red-300">
        {/* CSS: display: none */}
        <p>You cannot see me because I'm hidden.</p>
      </div>
      <div className="p-2 bg-gray-300">
        <p>Another visible container</p>
      </div>
    </div>
  );
}

States and Responsiveness

Hover and Focus States

Tailwind CSS supports dynamic and interactive behaviors using state-based variants like hover and focus, which can be prepended to utility classes to apply styles only when those states are active.

This is a live editor. Play around with it!
export default function BlockToGridHover() {
  return (
    <div className="w-full max-w-sm p-4 bg-gray-50">
      <h3 className="text-sm font-medium mb-4">Hover over the container:</h3>
      
      <div className="block hover:grid hover:grid-cols-2 hover:gap-2 hover:space-y-0 border-2 border-dashed border-blue-200 p-4 transition-all duration-200 space-y-4">
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 1</p>
        </div>
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 2</p>
        </div>
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 3</p>
        </div>
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 4</p>
        </div>
      </div>
      
      <p className="text-xs text-gray-500 mt-4">
        The boxes stack vertically by default (block), then arrange in a 2x2 grid on hover
      </p>
    </div>
  );
}

Breakpoint Modifiers

Tailwind CSS allows you to apply utility classes conditionally based on responsive breakpoints, using variants like sm:, md:, lg:, and more. By prefixing these modifiers to utility classes, the styles are applied only when the specified breakpoints are active.

This is a live editor. Play around with it!
export default function ResponsiveDisplay() {
  return (
    <div className="w-full max-w-sm p-4 bg-gray-50">
      <h3 className="text-sm font-medium mb-4">The below container will become grid on "md" breakpoint</h3>
      
      <div className="block md:grid md:grid-cols-2 md:gap-2 md:space-y-0 border-2 border-dashed border-blue-200 p-4 transition-all duration-200 space-y-4">
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 1</p>
        </div>
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 2</p>
        </div>
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 3</p>
        </div>
        <div className="bg-blue-100 p-4">
          <p className="text-sm">Box 4</p>
        </div>
      </div>
      
      <p className="text-xs text-gray-500 mt-4">
        The boxes stack vertically by default (block), then arrange in a 2x2 grid on "md" breakpoint
      </p>
    </div>
  );
}

Real World Examples

A responsive grid layout for featuring blog posts with images, titles, and excerpts.

This is a live editor. Play around with it!
function FeaturedBlogGrid() {
  const blogPosts = [
    {
      id: 1,
      title: "Ultimate Guide to Remote Work",
      excerpt: "Learn how to stay productive while working from home...",
      src: "https://images.unsplash.com/photo-1593642532744-d377ab507dc8",
      alt: "Person working on laptop from home office",
      author: "Sarah Chen",
      readTime: "8 min read"
    },
    {
      id: 2,
      title: "Mastering React Hooks",
      excerpt: "Deep dive into useState, useEffect and custom hooks...",
      src: "https://images.unsplash.com/photo-1633356122544-f134324a6cee",
      alt: "Code editor showing React code",
      author: "Mark Thompson",
      readTime: "12 min read"
    },
    {
      id: 3,
      title: "Sustainable Living Tips",
      excerpt: "Small changes that make a big environmental impact...",
      src: "https://images.unsplash.com/photo-1542601906990-b4d3fb778b09",
      alt: "Eco-friendly products laid out on table",
      author: "Emma Roberts",
      readTime: "6 min read"
    },
    {
      id: 4,
      title: "Photography Basics",
      excerpt: "Understanding composition, lighting, and camera settings...",
      src: "https://images.unsplash.com/photo-1452780212940-6f5c0d14d848",
      alt: "Camera lens closeup",
      author: "David Kim",
      readTime: "10 min read"
    },
    {
      id: 5,
      title: "Healthy Meal Prep Guide",
      excerpt: "Plan and prepare nutritious meals for the week...",
      src: "https://images.unsplash.com/photo-1547592180-85f173990554",
      alt: "Healthy meal prep containers",
      author: "Lisa Martinez",
      readTime: "9 min read"
    },
    {
      id: 6,
      title: "Personal Finance 101",
      excerpt: "Essential tips for budgeting and saving money...",
      src: "https://images.unsplash.com/photo-1554224155-6726b3ff858f",
      alt: "Calculator and financial documents",
      author: "James Wilson",
      readTime: "7 min read"
    }
  ];

  return (
    <div className="container mx-auto px-4">
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
        {blogPosts.map((post) => (
          <article key={post.id} className="bg-white rounded-lg shadow-md overflow-hidden">
            <img 
              src={post.src} 
              alt={post.alt}
              className="w-full h-48 object-cover"
            />
            <div className="p-6">
              <h3 className="text-xl font-bold mb-2">{post.title}</h3>
              <p className="text-gray-600 mb-4">{post.excerpt}</p>
              <div className="flex justify-between items-center text-sm text-gray-500">
                <span>{post.author}</span>
                <span>{post.readTime}</span>
              </div>
            </div>
          </article>
        ))}
      </div>
    </div>
  );
}

export default FeaturedBlogGrid;

E-commerce Category Showcase

A flex-based layout for showcasing product categories with hover effects and clear visual hierarchy.

This is a live editor. Play around with it!
function CategoryShowcase() {
  const categories = [
    {
      id: 1,
      name: "Smartphones",
      itemCount: "156 items",
      src: "https://images.unsplash.com/photo-1511707171634-5f897ff02aa9",
      alt: "Latest smartphone models display"
    },
    {
      id: 2,
      name: "Laptops",
      itemCount: "94 items",
      src: "https://images.unsplash.com/photo-1496181133206-80ce9b88a853",
      alt: "Modern laptops on desk"
    },
    {
      id: 3,
      name: "Headphones",
      itemCount: "78 items",
      src: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e",
      alt: "Premium headphones collection"
    },
    {
      id: 4,
      name: "Smartwatches",
      itemCount: "45 items",
      src: "https://images.unsplash.com/photo-1542496658-e33a6d0d50f6",
      alt: "Various smartwatch models"
    },
    {
      id: 5,
      name: "Cameras",
      itemCount: "67 items",
      src: "https://images.unsplash.com/photo-1516035069371-29a1b244cc32",
      alt: "Digital cameras showcase"
    },
    {
      id: 6,
      name: "Gaming",
      itemCount: "89 items",
      src: "https://images.unsplash.com/photo-1538481199705-c710c4e965fc",
      alt: "Gaming accessories collection"
    }
  ];

  return (
    <div className="container mx-auto px-4">
      <div className="flex flex-wrap -mx-4">
        {categories.map((category) => (
          <div key={category.id} className="w-full sm:w-1/2 lg:w-1/3 p-4">
            <div className="relative group overflow-hidden rounded-lg">
              <img 
                src={category.src} 
                alt={category.alt}
                className="w-full h-64 object-cover transition-transform duration-300 group-hover:scale-110"
              />
              <div className="absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center">
                <div className="text-center">
                  <h3 className="text-white text-2xl font-bold mb-2">{category.name}</h3>
                  <p className="text-white text-sm">{category.itemCount}</p>
                </div>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

export default CategoryShowcase;

Team Members Grid

A responsive team members grid that uses inline-block display for consistent spacing and alignment.

This is a live editor. Play around with it!
const TeamGrid = () => {
  const teamMembers = [
    {
      name: "Sarah Johnson",
      role: "Product Designer",
      src: "https://images.unsplash.com/photo-1494790108377-be9c29b29330",
      alt: "Sarah Johnson profile photo",
      social: { twitter: "@sarahj", linkedin: "sarahjohnson" }
    },
    {
      name: "Michael Chen",
      role: "Frontend Developer",
      src: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d",
      alt: "Michael Chen profile photo",
      social: { twitter: "@mikechen", linkedin: "michaelchen" }
    },
    {
      name: "Emma Williams",
      role: "UX Researcher",
      src: "https://images.unsplash.com/photo-1487412720507-e7ab37603c6f",
      alt: "Emma Williams profile photo",
      social: { twitter: "@emmaw", linkedin: "emmawilliams" }
    },
    {
      name: "David Kim",
      role: "Backend Developer",
      src: "https://images.unsplash.com/photo-1519345182560-3f2917c472ef",
      alt: "David Kim profile photo",
      social: { twitter: "@davidk", linkedin: "davidkim" }
    },
    {
      name: "Lisa Martinez",
      role: "Project Manager",
      src: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80",
      alt: "Lisa Martinez profile photo",
      social: { twitter: "@lisam", linkedin: "lisamartinez" }
    },
    {
      name: "James Wilson",
      role: "DevOps Engineer",
      src: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e",
      alt: "James Wilson profile photo",
      social: { twitter: "@jamesw", linkedin: "jameswilson" }
    }
  ];

  return (
    <div className="max-w-6xl mx-auto px-4 py-12">
      <div className="text-center mb-12">
        <h2 className="text-3xl font-bold mb-4">Our Team</h2>
        <p className="text-gray-600">Meet the talented people behind our success</p>
      </div>
      <div className="text-center">
        {teamMembers.map((member) => (
          <div
            key={member.name}
            className="inline-block w-64 m-4 text-left align-top bg-white rounded-lg shadow-md overflow-hidden"
          >
            <img
              src={member.src}
              alt={member.alt}
              className="w-full h-48 object-cover"
            />
            <div className="p-4">
              <h3 className="font-semibold text-lg">{member.name}</h3>
              <p className="text-gray-600">{member.role}</p>
              <div className="mt-4 space-x-4">
                <a href={`https://twitter.com/${member.social.twitter}`} className="text-blue-500 hover:text-blue-600">
                  Twitter
                </a>
                <a href={`https://linkedin.com/in/${member.social.linkedin}`} className="text-blue-500 hover:text-blue-600">
                  LinkedIn
                </a>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

export default TeamGrid;

Collapsible Navigation Menu

A responsive navigation with hamburger menu for mobile devices.

This is a live editor. Play around with it!
import React, { useState } from 'react';

const ResponsiveMenu = () => {
  const [isOpen, setIsOpen] = useState(false);

  const menuItems = [
    { label: "Dashboard", href: "#" },
    { label: "Products", href: "#" },
    { label: "Analytics", href: "#" },
    { label: "Settings", href: "#" },
    { label: "Support", href: "#" },
    { label: "Profile", href: "#" }
  ];

  return (
    <nav className="bg-white shadow">
      <div className="max-w-7xl mx-auto px-4">
        <div className="flex justify-between h-16">
          <div className="flex items-center">
            <span className="text-xl font-bold">Logo</span>
          </div>
          
          {/* Desktop Menu */}
          <div className="hidden md:flex items-center space-x-8">
            {menuItems.map((item) => (
              <a
                key={item.label}
                href={item.href}
                className="text-gray-700 hover:text-gray-900 px-3 py-2 rounded-md text-sm font-medium"
              >
                {item.label}
              </a>
            ))}
          </div>

          {/* Mobile Menu Button */}
          <div className="md:hidden flex items-center">
            <button 
              onClick={() => setIsOpen(!isOpen)}
              className="text-gray-700 hover:text-gray-900 focus:outline-none"
              aria-label="Toggle menu"
            >
              {isOpen ? (
                // X icon for close
                <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              ) : (
                // Hamburger icon for open
                <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
                </svg>
              )}
            </button>
          </div>
        </div>

        {/* Mobile Menu */}
        <div className={`md:hidden ${isOpen ? 'block' : 'hidden'}`}>
          <div className="px-2 pt-2 pb-3 space-y-1 sm:px-3">
            {menuItems.map((item) => (
              <a
                key={item.label}
                href={item.href}
                className="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50"
              >
                {item.label}
              </a>
            ))}
          </div>
        </div>
      </div>
    </nav>
  );
};

export default ResponsiveMenu;

Collapsible FAQ Section

A clean accordion interface using strategic display: block and display: none properties for progressive disclosure.

This is a live editor. Play around with it!
import {useState} from "react";

export const CollapsibleFAQ = () => {
  const [activeIndex, setActiveIndex] = useState(null);
  
  const faqs = [
    {
      question: "What is your return policy?",
      answer: "We offer a 30-day return policy for all unused items in original packaging."
    },
    {
      question: "How long does shipping take?",
      answer: "Standard shipping takes 3-5 business days within the continental US."
    },
    {
      question: "Do you ship internationally?",
      answer: "Yes, we ship to most countries. International shipping typically takes 7-14 business days."
    },
    {
      question: "What payment methods do you accept?",
      answer: "We accept all major credit cards, PayPal, and Apple Pay."
    },
    {
      question: "How can I track my order?",
      answer: "You'll receive a tracking number via email once your order ships."
    },
    {
      question: "Do you offer gift wrapping?",
      answer: "Yes, gift wrapping is available for an additional $5 per item."
    }
  ];

  return (
    <div className="w-full max-w-2xl mx-auto space-y-4">
      {faqs.map((faq, index) => (
        <div key={index} className="border rounded-lg overflow-hidden">
          <button
            className="w-full p-4 text-left bg-gray-50 hover:bg-gray-100 flex justify-between items-center"
            onClick={() => setActiveIndex(activeIndex === index ? null : index)}
          >
            <span className="font-medium">{faq.question}</span>
            <span className="transform transition-transform duration-200">
              {activeIndex === index ? '−' : '+'}
            </span>
          </button>
          <div className={`${activeIndex === index ? 'block' : 'hidden'} p-4 bg-white`}>
            {faq.answer}
          </div>
        </div>
      ))}
    </div>
  );
};

export default CollapsibleFAQ;

Best Practices

Maintain Design Consistency

Consistency is a fundamental principle when using display utilities in Tailwind CSS. These utilities, such as flex, grid, block, and others, allow you to structure your layouts efficiently. Decide on standard use cases for flex versus grid in your design system. While flex might be used for one-dimensional layouts like navigation bars, grid can be reserved for more complex, two-dimensional layouts like dashboards.

Creating reusable class patterns or design tokens for frequently used layouts can further enhance consistency. For instance, define a flex-row-center class that combines flex, items-center, and justify-center for centering flex children horizontally and vertically. Such patterns make it easier to maintain consistency while simplifying the development process.

Leverage Utility Combinations

Tailwind CSS utilities can be combined thoughtfully to create flexible designs. Display utilities, such as grid and flex, are really helpful when used with alignment and spacing utilities.

For example, combine grid with gap-* and place-items-* to create intuitive and visually appealing layouts. Similarly, flex can be paired with justify-*, items-*, and flex-* to create responsive, row-based layouts.

The key is to balance utility combinations for clarity and performance. Avoid overloading components with too many utilities, as this can make your code harder to read and maintain. Focus on combining utilities that complement each other to achieve your layout goals effectively.

Accessibility Considerations

Enhance Readability and Navigability

Using display utilities effectively can greatly enhance both the readability and navigability of your interface. By structuring content with flex or grid, you can create logical groupings and alignments that help users process information intuitively. For instance, using flex with justify-between for navigation links creates a clean and predictable layout, while grid can be ideal for organizing cards or dashboards.

When designing complex layouts, minimize unnecessary nesting, as it can reduce readability and complicate accessibility. Instead, keep your component hierarchy clean and leverage Tailwind’s utilities for alignment, spacing, and responsive adjustments.

Ensure Keyboard Accessibility

Keyboard navigation is a cornerstone of web accessibility, allowing users who rely on keyboards or assistive devices to interact with content. When using Tailwind CSS display utilities such as hidden, block, inline, etc., it’s critical to ensure that interactive elements remain navigable by keyboard.

When toggling visibility dynamically, such as opening a modal or dropdown, proper focus management is crucial. Focus should programmatically move to the newly visible element without requiring the user to manually tab through the page.

For example, when a modal opens, the focus should automatically shift to its first interactive element (e.g., a close button or input field). When the modal is closed, the focus should return to the element that triggered it (e.g., the button or link). To complement this, use the tabindex attribute to control the keyboard navigability of elements.