Display, Position & Overflow

Tailwind CSS · Lesson 10 of 27 7 min read Updated

Before you build rows and grids, you need the basic layout tools: how an element sits in the flow of the page (display), how to lift it out of that flow and place it exactly (position), which element appears on top (z-index), and what happens when content is too big for its box (overflow).

In this lesson you will learn these utilities with practical examples: a notification badge, a sticky header, a scrollable table and a dialog overlay. You will also see the new scrollbar utilities from Tailwind 4.3.

Display

Display utilities are a single word each:

ClassCSSBehaviour
blockdisplay: blockStarts on a new line, full width
inline-blockdisplay: inline-blockSits in a line of text but accepts width and padding
inlinedisplay: inlineFlows with text
flex, inline-flexFlexboxLays out children in a row or column
grid, inline-gridGridLays out children in rows and columns
hiddendisplay: noneRemoved from the page and from screen readers
contentsdisplay: contentsThe element's box disappears; its children act as if they were in the parent

hidden removes an element completely. invisible is different: the element is not shown but still takes up its space. Combine hidden with a breakpoint to show things on some screen sizes only, for example hidden md:block shows a sidebar only on medium screens and up. You will learn this in Responsive Design & Breakpoints.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Display</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="p-6">
  <p>Links as <code>inline</code>:
    <a href="#" class="inline bg-sky-100 px-2 py-2">Tea</a>
    <a href="#" class="inline bg-sky-100 px-2 py-2">Coffee</a>
  </p>
  <p class="mt-6">As <code>inline-block</code>:
    <a href="#" class="inline-block bg-sky-100 px-2 py-2">Tea</a>
    <a href="#" class="inline-block bg-sky-100 px-2 py-2">Coffee</a>
  </p>
  <div class="mt-6 flex gap-2">
    <span class="bg-amber-200 p-2">One</span>
    <span class="invisible bg-amber-200 p-2">Two (invisible)</span>
    <span class="bg-amber-200 p-2">Three</span>
  </div>
  <div class="mt-2 flex gap-2">
    <span class="bg-emerald-200 p-2">One</span>
    <span class="hidden bg-emerald-200 p-2">Two (hidden)</span>
    <span class="bg-emerald-200 p-2">Three</span>
  </div>
</body>
</html>

Look at the gap left by the invisible "Two" in the amber row, and the lack of a gap in the green row.

Position

Position utilities set the CSS position property: static (the default), relative, absolute, fixed and sticky. Then place the element with offset utilities that use the spacing scale:

  • top-0, right-4, bottom-2, left-1/2 set one side.
  • inset-0 sets all four sides to 0, so the element covers its container.
  • inset-x-0 and inset-y-0 set left and right, or top and bottom.
  • A minus sign gives negative offsets: -top-2 moves the element 0.5rem above the edge.

An absolute element is placed relative to its nearest positioned ancestor, so the usual pattern is relative on the parent and absolute on the child. Here is a notification badge on a cart button:

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Badge</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="p-10">
  <button class="relative rounded-lg bg-slate-800 px-4 py-2 text-white">
    Cart
    <span class="absolute -top-2 -right-2 flex size-6 items-center justify-center rounded-full bg-red-600 text-xs font-bold">3</span>
  </button>
  <div class="relative mt-10 w-64 rounded-xl border border-slate-200 p-4">
    <span class="absolute top-0 right-4 -translate-y-1/2 rounded-full bg-amber-400 px-3 py-0.5 text-xs font-semibold">New batch</span>
    <h3 class="font-semibold">Python for beginners</h3>
    <p class="text-sm text-slate-600">Starts 10 November, Pune</p>
  </div>
</body>
</html>

In the second card, top-0 puts the label on the top edge and -translate-y-1/2 moves it up by half its own height, so it sits exactly across the border line.

Sticky and fixed

fixed places an element relative to the browser window, so it stays put while the page scrolls: think of a floating "Chat with us" button. sticky is a mix: the element scrolls normally until it reaches its offset, such as top-0, then sticks there while its parent is still on screen. It is ideal for headers and table headings.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Sticky and scrolling</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-100 p-6">
  <div class="h-64 max-w-md overflow-y-auto rounded-xl bg-white scrollbar-thin scrollbar-thumb-sky-500 scrollbar-track-slate-100">
    <table class="w-full text-left text-sm">
      <thead class="sticky top-0 bg-sky-700 text-white">
        <tr><th class="p-3">Roll no.</th><th class="p-3">Name</th><th class="p-3">Marks</th></tr>
      </thead>
      <tbody class="divide-y divide-slate-100">
        <tr><td class="p-3">101</td><td class="p-3">Aarav</td><td class="p-3">88</td></tr>
        <tr><td class="p-3">102</td><td class="p-3">Ananya</td><td class="p-3">93</td></tr>
        <tr><td class="p-3">103</td><td class="p-3">Farhan</td><td class="p-3">79</td></tr>
        <tr><td class="p-3">104</td><td class="p-3">Isha</td><td class="p-3">91</td></tr>
        <tr><td class="p-3">105</td><td class="p-3">Kabir</td><td class="p-3">85</td></tr>
        <tr><td class="p-3">106</td><td class="p-3">Meera</td><td class="p-3">96</td></tr>
        <tr><td class="p-3">107</td><td class="p-3">Priya</td><td class="p-3">82</td></tr>
        <tr><td class="p-3">108</td><td class="p-3">Rohan</td><td class="p-3">77</td></tr>
      </tbody>
    </table>
  </div>
</body>
</html>

Scroll inside the box: the blue heading row stays at the top because of sticky top-0. A sticky element needs an opaque background, otherwise the rows show through it as they scroll underneath.

Overflow

When content is bigger than its box, overflow utilities decide what happens:

  • overflow-hidden clips anything outside the box. It is also how you make an image respect a card's rounded corners.
  • overflow-auto adds scrollbars only when needed. overflow-x-auto scrolls sideways only, which is the standard fix for wide tables on phones.
  • overflow-y-auto with a fixed height makes a scrollable panel, like the table above.
  • overscroll-contain stops the page behind a scrolling panel from scrolling when the panel reaches its end.

Z-index and stacking

When positioned elements overlap, z-* decides which one is on top: z-0, z-10, z-20 up to z-50, any other whole number such as z-60, and negative values like -z-10. Higher numbers sit on top. A common plan is z-10 for sticky headers, z-40 for dropdown menus and z-50 for dialogs and their dark backdrop:

HTML
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4">
  <div class="w-full max-w-sm rounded-xl bg-white p-6">Are you sure you want to cancel the booking?</div>
</div>

isolate starts a new stacking context, which keeps the z-index values inside a component from fighting with the rest of the page. See Z-index & Stacking Contexts for the full rules.

Common mistakes

  • absolute with no relative parent. The element is then placed relative to the whole page. Add relative to the container you mean.
  • Sticky that does not stick. A parent with overflow-hidden or a parent that is only as tall as the sticky element stops it. Also remember the top-0.
  • Huge z-index numbers. z-[9999] is a sign of a stacking problem. Use a small, planned set of values.
  • Hiding content from everyone. hidden also hides it from screen readers. To hide visually but keep it readable aloud, use sr-only (see Accessibility with Tailwind).

Key points

  • Display utilities are single words: block, inline-block, flex, grid, hidden; invisible keeps the space.
  • Put relative on the parent and absolute plus offsets such as -top-2 -right-2 on the child.
  • fixed sticks to the window; sticky top-0 sticks within its parent while scrolling.
  • overflow-x-auto makes wide tables scroll on phones; overflow-hidden clips to rounded corners.
  • Tailwind 4.3 adds scrollbar-thin, scrollbar-thumb-*, scrollbar-track-* and scrollbar-gutter-stable.
  • Use a small set of z-* values; isolate keeps a component's layers separate.

Exercise

Create a product card for a mobile shop in Lucknow. Put a "-20%" discount badge in the top-left corner over the product image ({{samples}}/landscape.svg), make sure the image follows the card's rounded corners, and add a "Buy now" bar that is fixed to the bottom of the window across its full width.

Show solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Product card</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-100 p-6 pb-24">
  <article class="relative max-w-xs overflow-hidden rounded-2xl bg-white">
    <img src="https://course.ethicscomputer.in/assets/samples/landscape.svg" alt="Phone with a scenic wallpaper" class="aspect-video w-full object-cover">
    <span class="absolute top-3 left-3 rounded-md bg-red-600 px-2 py-1 text-sm font-bold text-white">-20%</span>
    <div class="p-4">
      <h2 class="font-semibold">Galaxy-style phone, 128 GB</h2>
      <p class="text-slate-600">₹15,999</p>
    </div>
  </article>
  <div class="fixed inset-x-0 bottom-0 z-40 bg-white p-4 shadow-lg">
    <button class="w-full rounded-lg bg-sky-600 py-3 font-semibold text-white">Buy now</button>
  </div>
</body>
</html>

relative on the card lets the badge use absolute top-3 left-3, overflow-hidden clips the image to the rounded corners, and fixed inset-x-0 bottom-0 pins the bar to the bottom of the window. The extra pb-24 on the body stops the bar from covering the card.

Quick Quiz

1. What is the difference between hidden and invisible?

2. A badge with absolute -top-2 -right-2 appears in the corner of the whole page instead of its button. What is missing?

3. Which class makes a table header stay at the top while its container scrolls?

4. Which class lets a wide table scroll sideways on a phone instead of breaking the layout?

Learn Tailwind CSS with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call