Not long ago, we were completely reliant on using percentages for widths and heights. Using percentages meant that your layout and elements could assume a height and width based on the viewport. But as modern CSS continues to evolve, we have arrived at a point where it might even be a good idea to avoid using percentages.

Learn about the common problems you'll encounter when using percentages. Also find out about the modern CSS techniques to use in place of percentages. These techniques will give you the same result as percentages without any of the drawbacks.

A Very Simple Grid Example

To demonstrate a problem with percentage units, consider this HTML layout:

        <div class="container my-grid">
  <div class="grid-item">
  </div>
  <div class="grid-item">
  </div>
</div>

The outer element is a basic div container element with two div children. Each child has a grid-item class. To turn the container into a grid with two columns (two boxes), we'll need to apply the following CSS code:

        body {
  background-color: black;
  align-items: center;
  justify-content: flex-start;
}

.my-grid {
  display: grid;
  grid-template-columns: 50% 50%;
  margin: 3rem;
  border: 2px solid gold;
  padding: 1rem;
}

.grid-item {
  border: 3px solid gold;
  padding: 10rem 0;
  background: blue;
}

So each column (grid item) has a background color of gold. On the container parent class, we set grid-template-column to 50% for each column. As a result, both boxes take up 50% of the container element's total width.

Here's the result:

Screenshot of grid container without any gap

But there are problems with this alignment. First, if you decided to add a gap to the grid parent, the child could overflow out of the side. For example, if you were to add gap: 3px to the .my-grid block in the CSS, then here's how the layout would look:

Screenshot of grid container with an overflowing child

As you can see in the image above, the right box has moved out of the container. Sometimes you might not notice it because your gap is small enough, resulting in a weird alignment issue. But if you had a larger gap, then the overlap becomes quite obvious.

Whenever you're using percentages and adding margins or gaps, there's a huge chance of experiencing these kinds of errors. But why does the error occur?

It's because each column is 50% of the parent. In the above example, we have 50% plus 50% plus that gap (3px), which pushes the box out of the container.

Note that this error doesn't only happen with 50-50. You can set the first column to 75%, the second column to 25% and the error will still occur. This is why you need to use the following solution more often.

The Solution With Fractional Values

The solution is to use fractional values instead of percentages. So instead of setting the first column to 75% and the second to 50%, you can set the first column to 3fr and the second column to 1fr:

        grid-template-columns: 3fr 1fr
    

This maintains the same ratio as the first example. But the advantage of using fr units is that they're using a fraction of the available space. In this case, the first column will take three parts of the space while the second column will take one part, not including the gap.

Screenshot of grid container with fr values

Another advantage of using frs over percentages—or other absolute units, like px or em—is that you can combine them with fixed values. Here's an example:

grid-template-columns: 1fr 10rem;

With the code above, you'll get a fixed value that never changes regardless of the screen size. This is because the column on the right will always remain at 10rem while the column on the left will occupy the remaining space (minus the gap).

Sometimes you can get away with using percentages. But you have to use them in smart ways that can still adapt to the situation. Oftentimes, this means pairing them with an fr value.

A More Realistic Example

Let's imagine that you have a page that comprises the main content area and an aside (for related posts). The main content area takes up three fractions of the screen while the aside takes up the remaining space minus the gap:

        .container {
  width: 100%;
  display: grid;
  grid-template-columns: 3fr 1fr;
  gap: 1.5rem;
}

.card {
  background-color: #5A5A5A;
  padding: 10px;
  margin-bottom: .5rem;
}

Here's the result:

Screenshot of full page

Typically, you'd move the sidebar (or aside) to the bottom (or top) of the page once the screen becomes too narrow. This means setting up media queries that stack everything on top of each other when the viewport hits a certain breakpoint.

Here’s how you can stack everything into a column when the viewport hits 55em or less:

        @media(max-width: 55em) {
  .container {
    display: flex;
    flex-direction: column;
  }
}

And the result will look something like this:

Screenshot of grid with stacked elements

Now you don't want each card to span the width of the entire viewport. Rather the cards should display side-by-side. The best way to achieve this is with CSS grids. But instead of setting fixed width values (like 50%) for the grid-template-column, use the repeat() function as follows:

        .sidebar-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
    align-content: start;
    gap: 2rem;
}

This CSS sets a minimum size of 25rem and a maximum size of 1fr. That approach is much better than setting fixed widths because it relies on intrinsic sizing. In other words, it lets the browser figure things out based on available parameters.

Now when you reduce the browser window to a specific width, the grid box automatically readjusts to two boxes per line.

Screenshot of grid container with responsive items

When the screen becomes smaller, it drops to one box per line. So the browser stacks everything on top of one another. All of this happens as you resize the window. You can use a browser feature like Chrome DevTools to understand how this CSS works, and how resizing the windows changes the layout.

The best part is that you don't need a container query or anything fancy to make the element responsive. Simply set a grid and use min-max() to set fractional values instead of fixed sizes.

Learn More About CSS Grid

If you want to be great with CSS, you need to have deep knowledge of CSS Grids. Grids can be quite powerful when used well. You can achieve almost any layout you want using Grids. This makes it an indispensable tool in CSS.

One thing to keep in mind when using CSS grids is to focus on responsiveness. You can also use the fractional approach to avoid cases of collisions between elements. Remember to master CSS grids because the layout style will help you immensely when creating websites.