Display & Visibility
Display & Visibility in Tailwind CSS
Display and visibility utilities control how elements are rendered and whether they're visible to users and screen readers. Understanding these properties is essential for creating responsive layouts, hiding content conditionally, and building accessible interfaces.
Display Property
The display property is one of the most important CSS properties, determining how an element behaves in the layout:
Basic Display Values
<!-- Block display -->
<div class="block">
Block element (takes full width, stacks vertically)
</div>
<!-- Inline display -->
<span class="inline">Inline element</span>
<span class="inline">flows with text</span>
<!-- Inline-block display -->
<div class="inline-block">
Inline-block (flows like inline but respects width/height)
</div>
<!-- Flex display -->
<div class="flex">
<div>Flex item 1</div>
<div>Flex item 2</div>
</div>
<!-- Inline-flex display -->
<div class="inline-flex">
<div>Inline flex item 1</div>
<div>Inline flex item 2</div>
</div>
<!-- Grid display -->
<div class="grid grid-cols-3">
<div>Grid item 1</div>
<div>Grid item 2</div>
<div>Grid item 3</div>
</div>
<!-- Inline-grid display -->
<div class="inline-grid grid-cols-2">
<div>Item 1</div>
<div>Item 2</div>
</div>
<!-- Hidden (display: none) -->
<div class="hidden">
This element is completely removed from layout
</div>
block takes full width and forces new lines, inline flows with text, inline-block flows like inline but respects dimensions, and hidden removes the element entirely.
Block vs Inline vs Inline-Block
Comparing Display Types
<!-- Block elements -->
<div class="bg-blue-100 p-4 mb-2">
<div class="block bg-blue-500 text-white p-2 mb-2">Block 1 (full width)</div>
<div class="block bg-blue-500 text-white p-2">Block 2 (full width)</div>
</div>
<!-- Inline elements -->
<div class="bg-green-100 p-4 mb-2">
<span class="inline bg-green-500 text-white px-2 py-1">Inline 1</span>
<span class="inline bg-green-500 text-white px-2 py-1">Inline 2</span>
<span class="inline bg-green-500 text-white px-2 py-1">Inline 3</span>
</div>
<!-- Inline-block elements -->
<div class="bg-purple-100 p-4">
<div class="inline-block bg-purple-500 text-white px-4 py-2 w-24">IB 1</div>
<div class="inline-block bg-purple-500 text-white px-4 py-2 w-24">IB 2</div>
<div class="inline-block bg-purple-500 text-white px-4 py-2 w-24">IB 3</div>
</div>
<!-- Practical: Navigation menu -->
<nav class="bg-gray-800 p-4">
<a href="#" class="inline-block text-white px-4 py-2 hover:bg-gray-700 rounded">Home</a>
<a href="#" class="inline-block text-white px-4 py-2 hover:bg-gray-700 rounded">About</a>
<a href="#" class="inline-block text-white px-4 py-2 hover:bg-gray-700 rounded">Services</a>
<a href="#" class="inline-block text-white px-4 py-2 hover:bg-gray-700 rounded">Contact</a>
</nav>
Table Display Types
Tailwind provides utilities for table-related display values:
Table Display Examples
<!-- Table display -->
<div class="table w-full">
<div class="table-row-group">
<div class="table-row">
<div class="table-cell border border-gray-300 px-4 py-2">Cell 1</div>
<div class="table-cell border border-gray-300 px-4 py-2">Cell 2</div>
</div>
<div class="table-row">
<div class="table-cell border border-gray-300 px-4 py-2">Cell 3</div>
<div class="table-cell border border-gray-300 px-4 py-2">Cell 4</div>
</div>
</div>
</div>
<!-- Table caption -->
<div class="table w-full">
<div class="table-caption text-lg font-bold mb-2">Table Caption</div>
<div class="table-row-group">
<!-- Table content -->
</div>
</div>
Hidden vs Visibility
There are several ways to hide elements, each with different effects on layout and accessibility:
Different Ways to Hide Content
<!-- hidden (display: none) - removed from layout -->
<div class="hidden">
Completely removed from document flow
</div>
<!-- invisible (visibility: hidden) - space preserved -->
<div class="invisible">
Hidden but space is preserved in layout
</div>
<!-- opacity-0 - visually hidden but interactive -->
<div class="opacity-0">
Transparent but still in layout and clickable
</div>
<!-- sr-only (screen reader only) -->
<div class="sr-only">
Only visible to screen readers, not visual users
</div>
<!-- Comparison example -->
<div class="space-y-4">
<div class="flex gap-4 bg-gray-100 p-4">
<div class="bg-blue-500 text-white p-4">Visible</div>
<div class="hidden bg-red-500 text-white p-4">Hidden (no space)</div>
<div class="bg-blue-500 text-white p-4">Visible</div>
</div>
<div class="flex gap-4 bg-gray-100 p-4">
<div class="bg-blue-500 text-white p-4">Visible</div>
<div class="invisible bg-red-500 text-white p-4">Invisible (space kept)</div>
<div class="bg-blue-500 text-white p-4">Visible</div>
</div>
</div>
hidden and invisible hide content from screen readers. Use sr-only when you want content accessible to screen readers but hidden visually.
Visibility Property
Visibility Examples
<!-- Visible (default) -->
<div class="visible">
Visible element
</div>
<!-- Invisible -->
<div class="invisible">
Invisible but takes up space
</div>
<!-- Collapse (for table elements) -->
<table class="w-full">
<tr>
<td class="border p-2">Visible row</td>
</tr>
<tr class="collapse">
<td class="border p-2">Collapsed row (space removed)</td>
</tr>
<tr>
<td class="border p-2">Visible row</td>
</tr>
</table>
<!-- Toggle visibility with hover -->
<div class="group relative">
<button class="px-4 py-2 bg-blue-500 text-white rounded">
Hover me
</button>
<div class="invisible group-hover:visible absolute top-full left-0 mt-2 bg-white border border-gray-200 rounded-lg shadow-lg p-4">
<p>Tooltip content</p>
</div>
</div>
Opacity
Opacity controls how transparent an element is, with values from 0 (fully transparent) to 100 (fully opaque):
Opacity Examples
<!-- Opacity scale -->
<div class="space-y-4">
<div class="bg-blue-500 text-white p-4 opacity-0">opacity-0 (invisible)</div>
<div class="bg-blue-500 text-white p-4 opacity-25">opacity-25</div>
<div class="bg-blue-500 text-white p-4 opacity-50">opacity-50</div>
<div class="bg-blue-500 text-white p-4 opacity-75">opacity-75</div>
<div class="bg-blue-500 text-white p-4 opacity-100">opacity-100 (default)</div>
</div>
<!-- Hover opacity effect -->
<div class="grid grid-cols-3 gap-4">
<img src="image1.jpg" class="opacity-50 hover:opacity-100 transition-opacity" alt="Image 1">
<img src="image2.jpg" class="opacity-50 hover:opacity-100 transition-opacity" alt="Image 2">
<img src="image3.jpg" class="opacity-50 hover:opacity-100 transition-opacity" alt="Image 3">
</div>
<!-- Disabled button with opacity -->
<button class="bg-blue-500 text-white px-6 py-3 rounded disabled:opacity-50 disabled:cursor-not-allowed" disabled>
Disabled Button
</button>
<!-- Loading overlay -->
<div class="relative">
<div class="p-8 bg-white">
<h2 class="text-2xl font-bold">Content</h2>
<p>Main content here</p>
</div>
<div class="absolute inset-0 bg-black opacity-50 flex items-center justify-center">
<div class="bg-white p-4 rounded-lg opacity-100">
<p class="text-gray-900">Loading...</p>
</div>
</div>
</div>
Screen Reader Only
The sr-only utility hides content visually while keeping it accessible to screen readers:
Screen Reader Only Examples
<!-- Skip to main content link -->
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-0 focus:left-0 focus:bg-blue-500 focus:text-white focus:px-4 focus:py-2">
Skip to main content
</a>
<!-- Icon button with accessible label -->
<button class="p-2 rounded hover:bg-gray-100">
<svg class="w-6 h-6"><!-- Search icon --></svg>
<span class="sr-only">Search</span>
</button>
<!-- Form with accessible labels -->
<form>
<label for="email" class="sr-only">Email address</label>
<input
type="email"
id="email"
placeholder="Email address"
class="border border-gray-300 px-4 py-2 rounded w-full"
>
</form>
<!-- Loading indicator with accessible text -->
<div class="flex items-center justify-center">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>
<span class="sr-only">Loading content, please wait...</span>
</div>
<!-- Close button with label -->
<button class="absolute top-4 right-4 text-gray-400 hover:text-gray-600">
<svg class="w-6 h-6">×</svg>
<span class="sr-only">Close modal</span>
</button>
sr-only. This ensures all users can understand the purpose of interactive elements.
Responsive Display
Combine display utilities with responsive breakpoints to show/hide content at different screen sizes:
Responsive Display Examples
<!-- Mobile menu (visible on mobile, hidden on desktop) -->
<button class="block lg:hidden p-2">
<svg class="w-6 h-6"><!-- Menu icon --></svg>
<span class="sr-only">Open menu</span>
</button>
<!-- Desktop navigation (hidden on mobile, visible on desktop) -->
<nav class="hidden lg:block">
<a href="#" class="px-4 py-2">Home</a>
<a href="#" class="px-4 py-2">About</a>
<a href="#" class="px-4 py-2">Contact</a>
</nav>
<!-- Sidebar (full width on mobile, sidebar on desktop) -->
<div class="flex flex-col lg:flex-row">
<aside class="w-full lg:w-64 lg:block">
<!-- Sidebar content -->
</aside>
<main class="flex-1">
<!-- Main content -->
</main>
</div>
<!-- Show different content at different breakpoints -->
<div>
<p class="block sm:hidden">Mobile view</p>
<p class="hidden sm:block md:hidden">Tablet view</p>
<p class="hidden md:block">Desktop view</p>
</div>
<!-- Grid that changes columns -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="bg-gray-200 p-4">Item 1</div>
<div class="bg-gray-200 p-4">Item 2</div>
<div class="bg-gray-200 p-4">Item 3</div>
<div class="bg-gray-200 p-4">Item 4</div>
</div>
Practical Patterns
Modal Overlay
Modal with Display Control
<!-- Modal (toggle with JavaScript) -->
<div class="hidden fixed inset-0 z-50 overflow-y-auto" id="modal">
<!-- Background overlay -->
<div class="fixed inset-0 bg-black opacity-50"></div>
<!-- Modal content -->
<div class="flex min-h-full items-center justify-center p-4">
<div class="relative bg-white rounded-lg shadow-xl max-w-md w-full p-6">
<h2 class="text-2xl font-bold">Modal Title</h2>
<p class="mt-4">Modal content</p>
<button class="mt-6 px-4 py-2 bg-blue-500 text-white rounded">
Close
</button>
</div>
</div>
</div>
<script>
// Show modal: document.getElementById('modal').classList.remove('hidden')
// Hide modal: document.getElementById('modal').classList.add('hidden')
</script>
Accordion with Display Toggle
Accordion Example
<div class="space-y-2">
<!-- Accordion item -->
<div class="border border-gray-200 rounded-lg">
<button class="w-full flex items-center justify-between p-4 text-left hover:bg-gray-50">
<span class="font-semibold">Section 1</span>
<svg class="w-5 h-5"><!-- Chevron icon --></svg>
</button>
<div class="hidden p-4 border-t border-gray-200">
<p>Section 1 content</p>
</div>
</div>
<!-- Accordion item (expanded) -->
<div class="border border-gray-200 rounded-lg">
<button class="w-full flex items-center justify-between p-4 text-left hover:bg-gray-50">
<span class="font-semibold">Section 2</span>
<svg class="w-5 h-5 transform rotate-180"><!-- Chevron icon --></svg>
</button>
<div class="block p-4 border-t border-gray-200">
<p>Section 2 content (visible)</p>
</div>
</div>
</div>
Exercise 1: Create a Responsive Navigation
Build a navigation bar that:
- Shows a hamburger menu button on mobile (hidden on desktop)
- Shows full navigation links on desktop (hidden on mobile)
- Has a mobile menu that can be toggled (hidden by default)
- Uses proper screen reader labels for icon buttons
- Maintains accessibility throughout
Exercise 2: Build a Card Grid with Hover Effects
Create a product card grid where:
- Cards show 1 column on mobile, 2 on tablet, 4 on desktop
- Product images have opacity-50 by default, opacity-100 on hover
- "Add to Cart" button is invisible until card hover
- Price badge uses inline-block display
- Sale badge is hidden when not applicable
Exercise 3: Design an Accessible Loading State
Create a loading overlay that:
- Uses fixed positioning to cover the viewport
- Has a semi-transparent black background (opacity-50)
- Shows a loading spinner in the center
- Includes screen reader text describing the loading state
- Can be toggled with the hidden class
- Prevents interaction with content beneath
Summary
In this lesson, you've learned about display and visibility in Tailwind CSS:
- Display types: block, inline, inline-block, flex, grid, and table variants
- Hiding content: hidden, invisible, opacity, and sr-only
- Visibility property: visible, invisible, and collapse
- Opacity: Control transparency from 0 to 100
- Screen reader only: Hide content visually while keeping it accessible
- Responsive display: Show/hide content at different breakpoints
- Practical patterns: Modals, accordions, navigation, and loading states
Mastering display and visibility is essential for creating responsive layouts, managing content visibility, and building accessible interfaces. These utilities give you precise control over how elements are rendered and perceived by both visual users and assistive technologies.