March 30, 2024

Tailwind “Minimum Full Height” Layout

edit

I’ve been using Tailwind CSS on a lot of projects lately. Almost all my layouts for these projects are some version of the “minimum full height” layout, and I wanted to quickly show you how I do that with Tailwind.

The keys are:

  • html must be height: 100%
  • body must be min-height: 100%
  • body must be a Flex column container
  • main (or whatever element you choose) is flex-grow: 1

Here are the important pieces of the markup you’re looking for:

<html class="h-full">
  <body class="flex min-h-full flex-col">
    <header></header>
    <main class="grow"></main>
    <footer></footer>
  </body>
</html>

Percentage based heights only work if their parent element is a fixed height. In this case, since the topmost parent is set to the full height of the browser window, we can then also use a percentage based height on its direct child, the body element.

Because we want our body element to be able to extend beyond the full height of the browser when it has that much content, we only use min-h-full on it.

Next, by setting body as a Flex column layout, we can use the flex-grow property on one of its children to tell the layout engine, “expand this element to any remaining available space”. In this case, that’s the main element.

Thus, with this markup, our header and footer will take up the amount of space they require, and the main element will take up the rest to the full height of the browser if there is too little content to fill the space, and beyond if there is more than enough content.

Here’s a small example:

Header
Main
Footer

And that’s it. From there I encourage you to figure out the “holy grail” layout to further develop your skills and understanding.

Update - 2024-04-03

Multiple people on Twitter pointed out that it might be better to use h-dvh instead of h-full on the html element, and they’re correct. In some cases, most likely ones involving mobile browsers, it might be better to use h-dvh.

For those unfamiliar like I was, dvh stands for “dynamic viewport height”. I found this solid dev.to article breaking down the various units, so I don’t have to.

On mobile screens, h-dvh will track the full height and adjust if any other UI obstructs the viewport, such as the native navigation and such. So anything pinned to the bottom like our footer is, will track along with the viewport resizing as those bits of UI change.

So give h-dvh a try if you find h-full doesn’t do the trick.


Liked the post?
Give the author a dopamine boost with a few "beard strokes". Click the beard up to 50 times to show your appreciation.
Need help with your software problems?

My team and I are ready to help you. Hire Agathist to build your next great project or to improve one of your existing ones.

Get in touch
Kyle Shevlin's face, which is mostly a beard with eyes

Kyle Shevlin is the founder & lead software engineer of Agathist, a software development firm with a mission to build good software with good people.

Agathist
Good software by good people.
Visit https://agath.ist to learn more
Sign up for my newsletter
Let's chat some more about TypeScript, React, and frontend web development. Unsubscribe at any time.
Logo for Introduction to State Machines and XState
Introduction to State Machines and XState
Check out my courses!
If you enjoy my posts, you might enjoy my courses, too. Click the button to view the course or go to Courses for more information.