Tailwind CSS

Positioning & Z-Index

15 min Lesson 13 of 35

Positioning & Z-Index in Tailwind CSS

Understanding positioning and z-index is crucial for creating complex layouts, overlays, modals, and interactive components. Tailwind CSS provides intuitive utilities for controlling how elements are positioned and stacked on the page.

Position Property

The position property defines how an element is positioned in the document. Tailwind provides utilities for all CSS position values:

Position Types

<!-- Static (default) -->
<div class="static">
    Static positioning (normal document flow)
</div>

<!-- Relative -->
<div class="relative">
    Relative positioning (can use top/right/bottom/left)
</div>

<!-- Absolute -->
<div class="relative">
    <div class="absolute top-0 right-0">
        Absolute positioning (positioned relative to nearest positioned ancestor)
    </div>
</div>

<!-- Fixed -->
<div class="fixed top-0 left-0">
    Fixed positioning (relative to viewport)
</div>

<!-- Sticky -->
<div class="sticky top-0">
    Sticky positioning (switches between relative and fixed)
</div>
Key Difference: Static elements ignore top/right/bottom/left properties. All other position types can use positioning utilities.

Relative Positioning

Relative positioning allows you to offset an element from its normal position while maintaining its space in the document flow:

Relative Positioning Examples

<!-- Basic relative positioning -->
<div class="relative">
    This element is relatively positioned
</div>

<!-- Offset from normal position -->
<div class="relative top-4 left-8">
    Moved 16px down and 32px right from normal position
</div>

<!-- Relative parent for absolute children -->
<div class="relative bg-gray-100 p-8">
    <p>Parent container</p>
    <span class="absolute top-2 right-2 bg-blue-500 text-white px-2 py-1 rounded text-xs">
        Badge
    </span>
</div>

<!-- Card with relative positioning for badges -->
<div class="relative bg-white border border-gray-200 rounded-lg p-6">
    <div class="absolute -top-3 -right-3 bg-red-500 text-white w-8 h-8 rounded-full flex items-center justify-center text-sm font-bold">
        3
    </div>
    <h3 class="font-bold">Card Title</h3>
    <p class="text-gray-600 mt-2">Card content goes here</p>
</div>
Common Pattern: Use relative positioning on parent containers when you need to position child elements absolutely within them.

Absolute Positioning

Absolute positioning removes an element from the document flow and positions it relative to its nearest positioned ancestor:

Absolute Positioning Examples

<!-- Corner positioning -->
<div class="relative h-64 bg-gray-100">
    <div class="absolute top-0 left-0 bg-blue-500 text-white p-2">Top Left</div>
    <div class="absolute top-0 right-0 bg-green-500 text-white p-2">Top Right</div>
    <div class="absolute bottom-0 left-0 bg-yellow-500 text-white p-2">Bottom Left</div>
    <div class="absolute bottom-0 right-0 bg-red-500 text-white p-2">Bottom Right</div>
</div>

<!-- Centered element -->
<div class="relative h-64 bg-gray-100">
    <div class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-blue-500 text-white px-6 py-3 rounded">
        Perfectly Centered
    </div>
</div>

<!-- Full overlay -->
<div class="relative h-64 bg-gray-100">
    <img src="image.jpg" class="w-full h-full object-cover" alt="Background">
    <div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center">
        <h2 class="text-white text-3xl font-bold">Overlay Text</h2>
    </div>
</div>

<!-- Close button for modal -->
<div class="relative bg-white rounded-lg shadow-xl p-6">
    <button class="absolute top-4 right-4 text-gray-400 hover:text-gray-600">
        <svg class="w-6 h-6"><!-- X icon --></svg>
    </button>
    <h3 class="text-xl font-bold">Modal Title</h3>
    <p class="text-gray-600 mt-2">Modal content</p>
</div>

Inset Utilities

Inset utilities provide shorthand for setting multiple position properties at once:

Inset Examples

<!-- inset-0 = top:0, right:0, bottom:0, left:0 -->
<div class="relative h-64 bg-gray-100">
    <div class="absolute inset-0 bg-blue-500 bg-opacity-50">
        Covers entire parent
    </div>
</div>

<!-- inset-x = left and right -->
<div class="relative h-64 bg-gray-100">
    <div class="absolute inset-x-0 top-0 h-16 bg-blue-500">
        Spans full width at top
    </div>
</div>

<!-- inset-y = top and bottom -->
<div class="relative h-64 bg-gray-100">
    <div class="absolute inset-y-0 left-0 w-16 bg-green-500">
        Spans full height on left
    </div>
</div>

<!-- Inset with spacing -->
<div class="relative h-64 bg-gray-100">
    <div class="absolute inset-4 bg-purple-500 bg-opacity-50 rounded">
        16px margin on all sides
    </div>
</div>

<!-- Image with gradient overlay -->
<div class="relative h-96 rounded-lg overflow-hidden">
    <img src="hero.jpg" class="absolute inset-0 w-full h-full object-cover" alt="Hero">
    <div class="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent"></div>
    <div class="absolute inset-x-0 bottom-0 p-8">
        <h1 class="text-white text-4xl font-bold">Hero Title</h1>
        <p class="text-white text-lg mt-2">Hero description</p>
    </div>
</div>
Shorthand Values: inset-0 = all sides at 0, inset-x-0 = left and right at 0, inset-y-0 = top and bottom at 0.

Fixed Positioning

Fixed positioning positions elements relative to the viewport, making them stay in place during scrolling:

Fixed Positioning Examples

<!-- Fixed header -->
<header class="fixed top-0 left-0 right-0 bg-white shadow-md z-50">
    <nav class="container mx-auto px-4 py-4">
        <!-- Navigation content -->
    </nav>
</header>

<!-- Fixed footer -->
<footer class="fixed bottom-0 left-0 right-0 bg-gray-900 text-white">
    <div class="container mx-auto px-4 py-4">
        <!-- Footer content -->
    </div>
</footer>

<!-- Floating action button -->
<button class="fixed bottom-8 right-8 bg-blue-500 hover:bg-blue-600 text-white w-14 h-14 rounded-full shadow-lg flex items-center justify-center">
    <svg class="w-6 h-6">+</svg>
</button>

<!-- Cookie consent banner -->
<div class="fixed bottom-0 inset-x-0 bg-gray-900 text-white p-4">
    <div class="container mx-auto flex items-center justify-between">
        <p>We use cookies to improve your experience.</p>
        <button class="bg-blue-500 hover:bg-blue-600 px-4 py-2 rounded">Accept</button>
    </div>
</div>

<!-- Side chat widget -->
<div class="fixed bottom-4 right-4 w-80 bg-white rounded-lg shadow-2xl">
    <div class="bg-blue-500 text-white p-4 rounded-t-lg">
        <h3 class="font-bold">Chat with us</h3>
    </div>
    <div class="p-4 h-96 overflow-y-auto">
        <!-- Chat messages -->
    </div>
</div>
Important: When using fixed headers/footers, add appropriate padding to your main content to prevent it from being hidden behind them.

Sticky Positioning

Sticky positioning is a hybrid of relative and fixed positioning. The element is relative until it reaches a scroll threshold, then becomes fixed:

Sticky Positioning Examples

<!-- Sticky header -->
<header class="sticky top-0 bg-white shadow-md z-50">
    <nav class="container mx-auto px-4 py-4">
        <!-- Navigation that sticks to top when scrolling -->
    </nav>
</header>

<!-- Sticky sidebar -->
<div class="flex gap-8">
    <aside class="w-64 sticky top-20 self-start">
        <!-- Sidebar that sticks 20px from top -->
        <nav class="space-y-2">
            <a href="#" class="block p-2 hover:bg-gray-100 rounded">Link 1</a>
            <a href="#" class="block p-2 hover:bg-gray-100 rounded">Link 2</a>
        </nav>
    </aside>
    <main class="flex-1">
        <!-- Main content -->
    </main>
</div>

<!-- Sticky table header -->
<div class="overflow-auto max-h-96">
    <table class="w-full">
        <thead class="sticky top-0 bg-gray-100">
            <tr>
                <th class="px-4 py-2">Column 1</th>
                <th class="px-4 py-2">Column 2</th>
            </tr>
        </thead>
        <tbody>
            <!-- Table rows -->
        </tbody>
    </table>
</div>

<!-- Sticky section headers -->
<div class="space-y-8">
    <section>
        <h2 class="sticky top-0 bg-white py-4 text-2xl font-bold border-b">Section 1</h2>
        <!-- Section content -->
    </section>
    <section>
        <h2 class="sticky top-0 bg-white py-4 text-2xl font-bold border-b">Section 2</h2>
        <!-- Section content -->
    </section>
</div>
Pro Tip: Sticky positioning is perfect for navigation bars, table headers, and section titles that should remain visible while scrolling through content.

Z-Index

Z-index controls the stacking order of positioned elements. Higher values appear in front of lower values:

Z-Index Examples

<!-- Basic z-index layering -->
<div class="relative h-64">
    <div class="absolute inset-0 bg-blue-500 z-10">Layer 1 (z-10)</div>
    <div class="absolute inset-4 bg-green-500 z-20">Layer 2 (z-20)</div>
    <div class="absolute inset-8 bg-red-500 z-30">Layer 3 (z-30)</div>
</div>

<!-- Z-index values in Tailwind -->
<div class="z-0">z-index: 0</div>
<div class="z-10">z-index: 10</div>
<div class="z-20">z-index: 20</div>
<div class="z-30">z-index: 30</div>
<div class="z-40">z-index: 40</div>
<div class="z-50">z-index: 50</div>
<div class="z-auto">z-index: auto</div>

<!-- Modal overlay with proper z-index -->
<div class="fixed inset-0 bg-black bg-opacity-50 z-40">
    <div class="fixed inset-0 flex items-center justify-center z-50">
        <div class="bg-white rounded-lg p-8 max-w-md">
            <h2 class="text-2xl font-bold">Modal Title</h2>
            <p class="mt-4">Modal content</p>
        </div>
    </div>
</div>

<!-- Dropdown menu -->
<div class="relative">
    <button class="px-4 py-2 bg-blue-500 text-white rounded">Menu</button>
    <div class="absolute top-full left-0 mt-2 w-48 bg-white border border-gray-200 rounded-lg shadow-lg z-50">
        <a href="#" class="block px-4 py-2 hover:bg-gray-100">Item 1</a>
        <a href="#" class="block px-4 py-2 hover:bg-gray-100">Item 2</a>
    </div>
</div>
Z-Index Scale: Tailwind uses values 0, 10, 20, 30, 40, 50, and auto. This gives you enough layers for most use cases while maintaining consistency.

Practical Positioning Patterns

Sticky Header with Content

Complete Sticky Header Example

<!-- Full page layout with sticky header -->
<div class="min-h-screen">
    <!-- Sticky header -->
    <header class="sticky top-0 bg-white border-b border-gray-200 z-50">
        <div class="container mx-auto px-4">
            <nav class="flex items-center justify-between py-4">
                <div class="text-2xl font-bold">Logo</div>
                <div class="flex gap-6">
                    <a href="#" class="hover:text-blue-600">Home</a>
                    <a href="#" class="hover:text-blue-600">About</a>
                    <a href="#" class="hover:text-blue-600">Contact</a>
                </div>
            </nav>
        </div>
    </header>

    <!-- Main content -->
    <main class="container mx-auto px-4 py-8">
        <!-- Page content -->
    </main>
</div>

Overlay Modal

Complete Modal Example

<!-- Modal overlay (hidden by default, show with JavaScript) -->
<div class="fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
    <!-- Background overlay -->
    <div class="fixed inset-0 bg-black bg-opacity-75 transition-opacity"></div>

    <!-- Modal container -->
    <div class="flex min-h-full items-center justify-center p-4">
        <!-- Modal content -->
        <div class="relative transform overflow-hidden rounded-lg bg-white shadow-xl transition-all w-full max-w-lg">
            <!-- Close button -->
            <button class="absolute top-4 right-4 text-gray-400 hover:text-gray-600 z-10">
                <svg class="w-6 h-6">×</svg>
            </button>

            <!-- Modal body -->
            <div class="p-6">
                <h3 class="text-2xl font-bold text-gray-900" id="modal-title">
                    Modal Title
                </h3>
                <div class="mt-4">
                    <p class="text-gray-600">Modal content goes here</p>
                </div>
            </div>

            <!-- Modal footer -->
            <div class="bg-gray-50 px-6 py-4 flex justify-end gap-3">
                <button class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-100">
                    Cancel
                </button>
                <button class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600">
                    Confirm
                </button>
            </div>
        </div>
    </div>
</div>

Floating Elements

Floating Action Button and Notification

<!-- Floating action button (bottom right) -->
<button class="fixed bottom-8 right-8 bg-blue-500 hover:bg-blue-600 text-white w-16 h-16 rounded-full shadow-2xl flex items-center justify-center z-50 transition-transform hover:scale-110">
    <svg class="w-8 h-8">+</svg>
</button>

<!-- Notification toast (top right) -->
<div class="fixed top-4 right-4 bg-white border border-gray-200 rounded-lg shadow-lg p-4 max-w-sm z-50">
    <div class="flex items-start gap-3">
        <svg class="w-6 h-6 text-green-500 flex-shrink-0">✓</svg>
        <div class="flex-1">
            <h4 class="font-semibold text-gray-900">Success!</h4>
            <p class="text-sm text-gray-600 mt-1">Your changes have been saved.</p>
        </div>
        <button class="text-gray-400 hover:text-gray-600">
            <svg class="w-5 h-5">×</svg>
        </button>
    </div>
</div>

Tooltips

Tooltip Examples

<!-- Tooltip (show on hover with JavaScript) -->
<div class="relative inline-block">
    <button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
        Hover me
    </button>
    <!-- Tooltip content (hidden by default) -->
    <div class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 text-white text-sm rounded whitespace-nowrap opacity-0 invisible hover:opacity-100 hover:visible transition-all z-50">
        Tooltip text
        <!-- Arrow -->
        <div class="absolute top-full left-1/2 transform -translate-x-1/2 border-4 border-transparent border-t-gray-900"></div>
    </div>
</div>

<!-- Tooltip on the right -->
<div class="relative inline-block">
    <button class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600">
        Info
    </button>
    <div class="absolute left-full top-1/2 transform -translate-y-1/2 ml-2 px-3 py-2 bg-gray-900 text-white text-sm rounded whitespace-nowrap z-50">
        Additional information
    </div>
</div>

Exercise 1: Build a Card with Badge and Actions

Create a product card that includes:

  • Relative positioning on the card container
  • Absolutely positioned "Sale" badge in the top-right corner
  • Absolutely positioned favorite button in the top-left
  • Proper z-index so badges appear above the image
  • Hover effect that shows additional actions overlay

Exercise 2: Create a Sticky Sidebar Layout

Build a blog post layout with:

  • Sticky navigation header at the top
  • Sticky table of contents sidebar that follows scroll
  • Main content area with long-form text
  • Floating "back to top" button in the bottom-right
  • Proper z-index hierarchy for all elements

Exercise 3: Design a Modal with Multiple Layers

Create a modal system that features:

  • Fixed semi-transparent overlay covering the viewport
  • Centered modal container with proper z-index
  • Absolutely positioned close button
  • Fixed footer actions within the modal
  • Nested dropdown menu inside the modal with correct stacking
  • All elements properly layered so they don't conflict

Summary

In this lesson, you've learned about positioning and z-index in Tailwind CSS:

  • Position types: static, relative, absolute, fixed, sticky
  • Relative positioning: Create positioning context for absolute children
  • Absolute positioning: Position elements relative to nearest positioned ancestor
  • Inset utilities: Shorthand for positioning on multiple sides
  • Fixed positioning: Elements stay in viewport during scroll
  • Sticky positioning: Hybrid behavior that switches between relative and fixed
  • Z-index: Control stacking order with values from 0 to 50
  • Practical patterns: Sticky headers, modals, floating buttons, tooltips

Mastering positioning and z-index is essential for creating modern web interfaces with overlays, modals, dropdown menus, and complex layouts. These utilities give you precise control over element placement and stacking order.