TailwindCss layout with full screen height and scrolling content panel

Viewed 6002

I'm trying to create a typical html layout using TailwindCss - a fixed header and footer, with left-hand and right-hand sidebars.

The center content has a search function which is fixed - the content below should scroll.

I've tried utilising patterns from TailwindCss and TailwindUI, but can't get overflowing content (shown in light blue in the demo below) to scroll rather than pushing the page down.

<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet"/>
<div>
  <div class="h-screen flex flex-col bg-gray-300">
    <!-- header -->
    <div class="bg-blue-700 p-4">
      Nav
    </div>
    <div class="flex-grow flex flex-row justify-center">
      <!-- lhs -->
      <div class="flex-shrink-0 w-1/4 p-4">
        Left menu
      </div>
      <!-- center -->
      <div class="flex-1 flex flex-col bg-white">
        <div class="border-b-2 m-4 pb-2 border-gray-200">Search</div>
        <main class="flex-1 overflow-y-scroll p-4 bg-indigo-200">
          <div class="relative">
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
          </div>
        </div>
      </main>
      <!-- rhs -->
      <div class="flex-shrink-0 w-1/4 p-4">
        Right sidebar
      </div>
    </div>
    <!-- footer -->
    <div class="bg-blue-700 p-4">
      Footer
    </div>
  </div>
</div>

2 Answers

What's happening is the the middle div (which contains that center column we want to be scrollable) is being clamped to the height of its contents. Unless instructed otherwise, it'd rather do that, than overflow (at least on Chrome and Firefox). So our central column never even gets the opportunity to apply its own scroll behaviour.

The minimum solution is to put overflow-hidden on the middle div, to let it know it's okay for its contents to overrun:

<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet"/>
<div>
  <div class="h-screen flex flex-col bg-gray-300">
    <!-- header -->
    <div class="bg-blue-700 p-4">
      Nav
    </div>
    <div class="flex-grow flex flex-row overflow-hidden justify-center">
      <!-- lhs -->
      <div class="flex-shrink-0 w-1/4 p-4">
        Left menu
      </div>
      <!-- center -->
      <div class="flex-1 flex flex-col bg-white">
        <div class="border-b-2 m-4 pb-2 border-gray-200">Search</div>
        <main class="flex-1 overflow-y-auto p-4 bg-indigo-200">
          <div class="relative">
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
          </div>
        </div>
      </main>
      <!-- rhs -->
      <div class="flex-shrink-0 w-1/4 p-4">
        Right sidebar
      </div>
    </div>
    <!-- footer -->
    <div class="bg-blue-700 p-4">
      Footer
    </div>
  </div>
</div>

... as a result of which, the center column's overflow scroll behaviour becomes operational.

I've also suggested overflow-y-auto on the center column, so that the scrollbars are only when necessary.

This may not be the ideal solution, but it helps. Add this rule to your css:

main.flex-1.overflow-y-scroll.p-4.bg-indigo-200 {
    flex-basis: 0;
}

main.flex-1.overflow-y-scroll.p-4.bg-indigo-200 {
    flex-basis: 0;
}
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet"/>
<div>
  <div class="h-screen flex flex-col bg-gray-300">
    <!-- header -->
    <div class="bg-blue-700 p-4">
      Nav
    </div>
    <div class="flex-grow flex flex-row justify-center">
      <!-- lhs -->
      <div class="flex-shrink-0 w-1/4 p-4">
        Left menu
      </div>
      <!-- center -->
      <div class="flex-1 flex flex-col bg-white">
        <div class="border-b-2 m-4 pb-2 border-gray-200">Search</div>
        <main class="flex-1 overflow-y-scroll p-4 bg-indigo-200">
          <div class="relative">
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
            <div class="mb-64">Overflowing content</div>
          </div>
        </div>
      </main>
      <!-- rhs -->
      <div class="flex-shrink-0 w-1/4 p-4">
        Right sidebar
      </div>
    </div>
    <!-- footer -->
    <div class="bg-blue-700 p-4">
      Footer
    </div>
  </div>
</div>

Related