Nowadays, we are facing many problems concerning creating website layouts. Especially when it’s expected that they look good on every type of screen. There are several tools that can help us, like grid systems or open libraries, but what to do when we want to create our own layout using only CSS?

Luckily, there’s a solution for that, too. Oh, wait! Actually, there are two of them: CSS Flexbox and Grid.

CSS Flexbox

CSS Flexbox was introduced earlier than its younger brother, CSS Grid. It quickly became the new standard for positioning elements in a container, giving developers the possibility to easily adapt them using media-queries.

But how does it work and what makes it special? We can say that CSS Flexbox is content-dependent. It tries to adjust elements to take the optimal space in their container depending on what’s inside of them.

Let’s take a look at some code:

We can set the default element width and decide how an element should behave when there is not enough space in the wrapper (or when there’s too much of it).

Flex grow is set to 1 (with base width set to 150px). When an element is wrapped to a new line, it gets all the available space.

Here’s how it works with flex grow set to 0:

With flex grow set to 0, all the elements are taking the flex basis width (here set to 150px).

Additionally, we can set the position of the elements in relation to each other without any calculations:

This property has many more variations, giving us plenty of possibilities to rearrange elements as we like.

One more thing to mention, and I think it may be the most important one: CSS Flexbox is one axis-oriented. It means that we can place elements in rows or columns, but not in both directions at the same time.

It’s worth remembering that after changing flex direction to column, not only the axis itself will change (from horizontal to vertical), but also all of its corresponding properties. So, for example, flex basis will work in axis Y.

However, it won’t change the axis of the content itself.

Here, the flex basis is set to 150px (basically the width), but because we have changed the direction to “column” – it grows in axis Y.

For those of you who are still not convinced that Flexbox is a powerful solution that can be used in a wide variety of cases: what If I tell you that you can reorder your items as you please? And just by giving them ordering numbers!

Let’s take a look at our previous example:

And now, let’s put the last item at the beginning by simply doing this little thing:

Be aware of one important fact, though: the code shown above can be considered an ugly workaround – but it’s here just to show you an example, I hope I will be forgiven.

I did it this way because, by default, all Flexbox elements are ordered with value 0, and they are displayed as source order provided in HTML (as they have the same order value, this is the only way to order them).

Basically, we need to order every element in our container for the ordering be done right, so that would present like:

Which would give exactly the same effect.

I think it’s worth mentioning, because ordering behavior can also be controlled by media-queries and will help us to adjust the placement of the items as we please.

But which browser likes to cooperate with Flexbox? The answer is: all of them, including IE 10 and 11 (with small hiccups, but still).

We can use Flexbox almost everywhere nowadays. (Source:

We can use Flexbox almost everywhere nowadays.

If you happen to have an issue, though, do not despair! The Flexbox community has been struggling with various unexpected issues in different browsers. To help each other, they have created a small Github repo with readme, where you can find a list of such unusual behaviors. They’re nicely described, with fixes and workarounds.

Here’s the link:

CSS Grid

On the other hand, we have the CCS Grid layout. Grid is a pretty powerful layouting system that enables us to organize the elements as a whole in the desired container.

Here’s how it looks in code:

It’s worth remembering that the Grid layout system is container-based (opposite to Flexbox, which is content-based). This means that we can control the placement of containers, but we can’t control the placement of the elements inside them.

There’s one small but very useful thing that is possible with Grid but not with Flexbox (well, at least not out of the box), namely – we can put gaps between elements. In Flexbox, we have to use various workarounds to have the desired effect. In Grid, it’s enough to use one short line:

And that’s it! No negative margins or invisible borders necessary.

CSS Grid gives us a fluid element system that can provide responsive behavior without using media queries:

The auto-fit property takes care of filling elements in given spaces without a single media-query.

Quick note: this only works with the “repeat” column template. In other cases, we still need media-queries.

But there’s still so much more that we can do! You already know the Flexbox ordering capabilities – we have something similar in Grid. Or something even better: a very powerful variation of grid-areas. It enables us to name our elements and arrange them in our grid layout using these names.

Here’s how it works:

This looks exactly the same as our first CSS grid example, but let’s go further – let’s say I want the sidebar to be stretched all the way down to the bottom. Content and footer elements should be exactly the same width. So let’s introduce a small change:

Aside stretched all the way down with one, very simple change.

It’s super easy and, as you probably already know, it can be used to perform various layout changes in the entire application (with a little help from media-queries, of course). Personally, I like this solution a lot more than the Flexbox one since we don’t need to count the grid lines – we can see the “template” right in front of us.

Last but not least, the Grid layout system is two-dimensional. We can place containers in two dimensions, we don’t have to choose just one axis. Basically, we can place our grid elements in any place in the grid, even go beyond the given grid areas:

Our grid is by default divided into two columns. But using grid areas, we can expand elements to fill bigger spaces (like header and footer in this example). Here we can also see how browser see our grid areas.

So, can we already use CSS Grid on all browsers? Well, it’s almost there. The important thing to mention here is that Internet Explorer 10 and 11 use an old implementation of this feature (with partial support only). So if you are developing an app for this browser – please check the documentation.


CSS Flexbox vs Grid

Yet the main question is: which is better, CSS Flexbox or Grid? And the answer isn’t obvious, because these two layout systems were created to provide solutions to different types of problems.

I think the best way to put it is:
For managing the main layout of your site – use the Grid layout, but for controlling elements inside of it – use Flexbox.

(Or at least that’s the most logical explanation to me.)

That leads us to the conclusion that we can use both of the layouts at the same time:


I hope this article puts a little light on how Grid and Flexbox are different yet still can work together. It covers the fundamental information, and I’m sure that when you go deeper into the matter, you will find more cases where you can use them separately and others, in which they give the best results when combined.

Łukasz Milik

Frontend Developer who loves to play video games but doesn’t mind throwing a K20 dice from time to time as well. He loves to cook and bake, and the gym where he goes to weightlift is his second home. His professional specialty is HTML, CSS, and Angular – and he’s always happy to help, so if you happen to have any questions, don’t hesitate to reach out to him.