Rebuilding FIFA Standings Layout with CSS Subgrid 🔥 Build any web layout, with confidence.<br>Checkout The Layout Maestro course. Learn more
Switch to dark
Rebuilding FIFA Standings Layout with CSS Subgrid<br>A look at how to rebuild the FIFA standings layout by using CSS grid, subgrid, and more.<br>Jul 19, 2026
Table of contents
--> When I see an interesting layout, I can’t stop myself from opening the DevTools and seeing how it’s built. Most of the time, I find the layouts are built in a hacky way. That’s when I got curious about exploring it myself, and that’s how this article was born.
The problem
While looking at the FIFA standings page, I thought to myself: how did they build this layout in CSS? Take a look:
I opened the DevTools and started looking around. The standings table consists of the following rounds:
Round of 32
Round of 16
Quarter-finals
Final / Semi-finals / Third place play-off
On the FIFA website, each column is in its own element, even the ones that are related to each other, for example the round of 32 teams.
FIFA’s markup
Here is a simplified version of the markup:
div class="rounds"><br>div class="round round-of-8 start">div><br>div class="round round-of-4 start">div><br>div class="round round-of-2 start">div><br>div class="round semi-finals start">div><br>div class="round semi-finals end">div><br>div class="round round-of-8 end">div><br>div class="round round-of-4 end">div><br>div class="round round-of-2 end">div><br>div>
This is a classic example of making the markup reflect the design. To make it clearer, here is a video of the layout along with the markup.
I consider this a hack to mimic the design. If I were to write the markup, it would look like this:
div class="rounds"><br>div class="round round-of-8"><br>div class="start">div><br>div class="end">div><br>div><br>div class="round round-of-4"><br>div class="start">div><br>div class="end">div><br>div><br>div class="round round-of-2"><br>div class="start">div><br>div class="end">div><br>div><br>div class="round finals">div><br>div>
But the question is, how can we achieve this layout in CSS given the above markup? I will explain that in the article. For now, let’s see how it behaves at smaller sizes.
How it behaves at smaller sizes
At tablet-like sizes, the layout is scrollable, but remains the same as on larger sizes.
At the smallest size, all the rounds are left-aligned, from the round of 32 to the finals. For example, all the round of 32 teams are in the same column, not split between the left and right sides.
Building the layout
Before diving into my suggestion for the layout, I want to confirm the following:
This is just a suggestion that might contain mistakes.
I’m not handling the animations or the hover effects, as this article focuses on the layout only.
I’m using an abstracted version of the names, so you might find round of 8 instead of round of 32, but the idea is the same.
The first thing I thought about was using CSS Grid. I divided the layout into columns and rows.
The main grid
First, I defined a grid with a specific number of columns and rows.
.rounds {<br>display: grid;<br>grid-template-columns: repeat(8, minmax(30px, 1fr));<br>grid-template-rows: repeat(4, 32px);<br>gap: 0.5rem;
Here is the grid layout.
Item 1
Item 2
Item 3
Item 4
Item 4
Item 5
Item 6
Item 7
Item 7
Item 8
Item 9
Item 9
Item 10
Item 11
Item 11
Item 12
Item 13
Item 14
Item 15
In this grid, we will need to position the start and end of each round at the opposite ends of the grid. How we can do that? CSS subgrid for the rescue!
Nesting rounds with subgrid
Thanks to subgrid, we can nest a grid on the inner items. That means we can have two children positioned at the start and end of the shared grid.
Let’s take the first round as an example. First, I want to make the round span the entire grid.
div class="rounds"><br>div class="round round-of-8"><br>div class="start">div><br>div class="end">div><br>div><br>div>
.rounds {<br>display: grid;<br>grid-template-columns: repeat(8, minmax(30px, 1fr));<br>grid-template-rows: repeat(4, 32px);
.round-of-8 {<br>grid-column: 1 / -1;<br>grid-row: 1 / -1;
Here is the current result. I highlighted the items with colors so we can identify the start and end items.
Item 1
Item 2
Item 3
Item 4
Item 4
Item 5
Item 6
Item 7
Item 7
Item 8
Item 9
Item 9
Item 10
Item 11
Item 11
Item 12
Item 13
Item 14
Item 15
The .start and .end items are part of .round. What we want to do is make the .round-of-32 inherit the same grid, then place the .start and .end items where we need.
.round-of-8 {<br>grid-column: 1 / -1;<br>grid-row: 1 / -1;<br>display: grid;<br>grid-template-columns: subgrid;<br>grid-template-rows: subgrid;
I added subgrid to both columns and rows, so now the .round-of-32 element inherits the grid from its parent.
Item 1
Item 2
Item 3
Item 4
Item 4
Item 5
Item 6
Item 7
Item 7
Item 8
Item 9
Item 9
Item 10
Item 11
Item 11
Item 12
Item 13
Item 14
Item 15
It might not be totally clear, so here is a demo with controls you can play with. Change the...