Aug 16, 2022

Create dynamic page layouts

Create common layouts for your pages, such as grids and columns.

Layouts, such as columns and grids, can be easily achieved using components and Tailwind flex and grid classes. They are equally easy to make reponsive.

Column layout

A basic column layout can be achieved using either the flex or grid display classes. Here is an example with flex:

<div className="flex flex-col sm:flex-row gap-4">
  <div className="flex-grow ...">{/* ... */}</div>
  <div className="flex-grow ...">{/* ... */}</div>
</div>

This results in the following evenly sized 2-column layout:

Notice how we use flex-col sm:flex-row to arrange items in a column on mobile, and in a row on larger screens. We also use gap-4 to specify that spacing between the columns.

Growing a column

You can specify how columns should grow using flex-grow (grow as much as possible) and flex-none (don't grow).

<div className="flex flex-col sm:flex-row gap-4">
  <div className="flex-none w-24 ...">{/* ... */}</div>
  <div className="flex-grow ...">{/* ... */}</div>
  <div className="flex-none w-24 ...">{/* ... */}</div>
</div>

Some more options can be found in the Tailwind CSS documentation.

Grid layout

Grid layouts can be created using the Tailwind grid class.

<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 ...">{/* ... */}</div>
</div>

This results in the following:

Notice again how we use grid-cols-1 sm:grid-cols-3 to create a 1-column grid on mobile, and a 3-column grid on larger screens. We also use gap-4 to specify that spacing between each item.

Adjusting column span

If you want an item to span more than one column, you can use the col-span- class:

<div className="grid grid-cols-1 sm:grid-cols-5 gap-4">
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 col-span-2 ...">{/* ... */}</div>
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 ...">{/* ... */}</div>
  <div className="h-48 col-span-2 ...">{/* ... */}</div>
  <div className="h-48 col-span-3 ...">{/* ... */}</div>
</div>

Read more about the options for flex and grid layouts in the Tailwind CSS documentation.

Full page layout

Now, let's bring it all together and build a page that looks like this:

Link 1 Link 2 Link 3
Post 1 Post 2 Post 3

The navigation bar

First, let's add the navigation bar at the top:

<div className="flex flex-col">
  <div className="flex flex-row flex-none border-b items-center p-4 gap-4">
    <a href="/">Link 1</a>
    <a href="/">Link 2</a>
    <a href="/">Link 3</a>
  </div>
</div>
Link 1 Link 2 Link 3

The page container uses a flex flex-col layout for a vertical layout. The navigation bar uses a flex flex-row layout to horizontally place its children links. flex-none indicates that the navigation bar should not grow vertically.

The sidebar

Let's add the sidebar:

<div className="flex flex-col">
  <div className="flex flex-row flex-none border-b items-center p-4 gap-4">
    <a href="/">Link 1</a>
    <a href="/">Link 2</a>
    <a href="/">Link 3</a>
  </div>
  <div className="flex flex-row flex-grow">
    <div className="flex flex-col flex-none p-4 gap-4 border-r">
      <a href="/">Post 1</a>
      <a href="/">Post 2</a>
      <a href="/">Post 3</a>
    </div>
  </div>
</div>
Link 1 Link 2 Link 3
Post 1 Post 2 Post 3

We've first added a main container (for the sidebar and content), which has the flex-grow class, indicating that it should fill as much as it can (vertically), and a flex flex-row class indicating that items within it should be positioned horizontally.

The sidebar has the class flex flex-col for its children links to be positioned in a column layout (that is, vertically).

The main content

Finally, we can add the main content.

<div className="flex flex-col">
  <div className="flex flex-row flex-none border-b items-center p-4 gap-4">
    <a href="/">Link 1</a>
    <a href="/">Link 2</a>
    <a href="/">Link 3</a>
  </div>
  <div className="flex flex-row flex-grow">
    <div className="flex flex-col flex-none p-4 gap-4 border-r">
      <a href="/">Post 1</a>
      <a href="/">Post 2</a>
      <a href="/">Post 3</a>
    </div>
    <div className="flex flex-col flex-grow p-4">
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
        <div className="bg-gray-100 h-32 rounded-md" />
        <div className="bg-gray-100 h-32 rounded-md" />
        <div className="bg-gray-100 h-32 rounded-md" />
        <div className="bg-gray-100 h-32 rounded-md" />
        <div className="bg-gray-100 h-32 rounded-md" />
        <div className="bg-gray-100 h-32 rounded-md" />
        <div className="bg-gray-100 h-32 rounded-md" />
        <div className="bg-gray-100 h-32 rounded-md" />
      </div>
    </div>
  </div>
</div>
Link 1 Link 2 Link 3
Post 1 Post 2 Post 3

This container has the flex-grow class to make it fill the remaining space (horizontally). Furthermore, it has the grid grid-cols-2 sm:grid-cols-4 class, which takes care of positioning all the children in a grid layout. For small screens, two columns are used (grid-cols-2), and for large screens, four columns are used (grid-cols-4).

Adding the layout to a template

You will typically want to reuse such a layout for several pages, without having to copy it to each new page. Read the article on Templates for how to achieve this.