Thursday, August 20, 2026
HomeCSSRebuilding FIFA Standings Format with CSS Subgrid

Rebuilding FIFA Standings Format with CSS Subgrid


Once I see an fascinating structure, I can’t cease myself from opening the DevTools and seeing the way it’s constructed. More often than not, I discover the layouts are in-built a hacky method. That’s after I obtained inquisitive about exploring it myself, and that’s how this text was born.

The issue

Whereas trying on the FIFA standings web page, I believed to myself: how did they construct this structure in CSS? Have a look:

I opened the DevTools and began trying round. The standings desk consists of the next rounds:

  • Spherical of 32
  • Spherical of 16
  • Quarter-finals
  • Closing / Semi-finals / Third place play-off

On the FIFA web site, every column is in its personal ingredient, even those which might be associated to one another, for instance the spherical of 32 groups.

FIFA’s markup

Here’s a simplified model of the markup:

<div class="rounds">
  <div class="spherical round-of-8 begin"></div>
  <div class="spherical round-of-4 begin"></div>
  <div class="spherical round-of-2 begin"></div>
  <div class="spherical semi-finals begin"></div>
  <div class="spherical semi-finals finish"></div>
  <div class="spherical round-of-8 finish"></div>
  <div class="spherical round-of-4 finish"></div>
  <div class="spherical round-of-2 finish"></div>
</div>

This can be a traditional instance of constructing the markup replicate the design. To make it clearer, here’s a video of the structure together with the markup.

I contemplate this a hack to imitate the design. If I had been to write down the markup, it could appear to be this:

<div class="rounds">
  <div class="spherical round-of-8">
    <div class="begin"></div>
    <div class="finish"></div>
  </div>
  <div class="spherical round-of-4">
    <div class="begin"></div>
    <div class="finish"></div>
  </div>
  <div class="spherical round-of-2">
    <div class="begin"></div>
    <div class="finish"></div>
  </div>
  <div class="spherical finals"></div>
</div>

However the query is, how can we obtain this structure in CSS given the above markup? I’ll clarify that within the article. For now, let’s see the way it behaves at smaller sizes.

The way it behaves at smaller sizes

At tablet-like sizes, the structure is scrollable, however stays the identical as on bigger sizes.

On the smallest measurement, all of the rounds are left-aligned, from the spherical of 32 to the finals. For instance, all of the spherical of 32 groups are in the identical column, not cut up between the left and proper sides.

Constructing the structure

Earlier than diving into my suggestion for the structure, I need to verify the next:

  • That is only a suggestion which may comprise errors.
  • I’m not dealing with the animations or the hover results, as this text focuses on the structure solely.
  • I’m utilizing an abstracted model of the names, so that you would possibly discover spherical of 8 as an alternative of spherical of 32, however the concept is identical.

The very first thing I considered was utilizing CSS Grid. I divided the structure into columns and rows.

The principle grid

First, I outlined a grid with a particular variety of columns and rows.

.rounds {
  show: grid;
  grid-template-columns: repeat(8, minmax(30px, 1fr));
  grid-template-rows: repeat(4, 32px);
  hole: 0.5rem;
}

Right here is the grid structure.

On this grid, we might want to place the beginning and finish of every spherical on the reverse ends of the grid. How we will try this? CSS subgrid for the rescue!

Nesting rounds with subgrid

Due to subgrid, we will nest a grid on the inside gadgets. Meaning we will have two kids positioned in the beginning and finish of the shared grid.

Let’s take the primary spherical for example. First, I need to make the spherical span the whole grid.

<div class="rounds">
  <div class="spherical round-of-8">
    <div class="begin"></div>
    <div class="finish"></div>
  </div>
</div>
.rounds {
  show: grid;
  grid-template-columns: repeat(8, minmax(30px, 1fr));
  grid-template-rows: repeat(4, 32px);
}

.round-of-8 {
  grid-column: 1 / -1;
  grid-row: 1 / -1;
}

Right here is the present consequence. I highlighted the gadgets with colours so we will determine the beginning and finish gadgets.

The .begin and .finish gadgets are a part of .spherical. What we need to do is make the .round-of-32 inherit the identical grid, then place the .begin and .finish gadgets the place we’d like.

.round-of-8 {
  grid-column: 1 / -1;
  grid-row: 1 / -1;
  show: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
}

I added subgrid to each columns and rows, so now the .round-of-32 ingredient inherits the grid from its dad or mum.

It won’t be completely clear, so here’s a demo with controls you’ll be able to play with. Change the grid-column-start and grid-column-end values to see how the nested grid behaves (Be aware: this may change the location of the .round-of-32 ingredient in the primary grid).

<div class="rounds">

<div class="spherical round-of-8">

<div class="begin"></div>

<div class="finish"></div>

</div>

</div>

.round-of-8 {

show: grid;

grid-template-columns: subgrid;

grid-template-rows: subgrid;

grid-column-start: 1;

grid-column-end: -1;

grid-row: 1 / -1;

}

Positioning begin and finish

Primarily based on that, we will now place the .begin and .finish gadgets the place we’d like. For instance, I need the .begin ingredient to be within the first column, and the .finish ingredient to be within the final column.

.begin {
  grid-column: 1;
  grid-row: 1 / -1;
}

.finish {
  grid-column: -2;
  grid-row: 1 / -1;
}

Here’s what I did:

  • Positioned the .begin within the first column, spanning all of the rows.
  • Positioned the .finish within the final column utilizing -2. I can manually set the grid-column to the precise line quantity (8), but when I do, I might want to change it each time the grid columns change.

<div class="rounds">

<div class="spherical round-of-8">

<div class="begin"></div>

<div class="finish"></div>

</div>

</div>

.begin {

grid-column: 1;

grid-row: 1 / -1;

}

.finish {

grid-column: -2;

grid-row: 1 / -1;

}

Including extra rounds

Now that we’ve the structure working with the primary spherical, it’s time so as to add extra rounds and lay them out.

Right here, I added the second spherical to the structure. For now, the kid gadgets are stacked, however we’ll repair that later.

.round-of-4 {
  show: grid;
  grid-column: 2 / -2;
  grid-row: 1 / -1;
}

The following step is to move the dad or mum’s grid to the .round-of-16 ingredient once more, then place the beginning and finish gadgets the place we’d like.

.round-of-4 {
  show: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
  grid-column: 2 / -2;
  grid-row: 1 / -1;
}

Check out the next interactive demo the place you’ll be able to:

  • Change between rounds (the outlined spherical is the at the moment chosen one)
  • As soon as you turn, attempt altering the beginning/finish values for the .begin and .finish gadgets

<div class="rounds">

<div class="spherical round-of-8">

<div class="begin"></div>

<div class="finish"></div>

</div>

<div class="spherical round-of-4">

<div class="begin"></div>

<div class="finish"></div>

</div>

<div class="spherical round-of-2">

<div class="begin"></div>

<div class="finish"></div>

</div>

</div>

.round-of-8 {

grid-column: 1 / -1;

grid-row: 1 / -1;

}

.begin {

grid-column: 1;

grid-row: 1 / -1;

}

.finish {

grid-column: -1;

grid-row: 1 / -1;

}

Did you see how utilizing CSS grid and subgrid provides the structure a lot flexibility? There is no such thing as a want to put the kid gadgets into fully totally different wrappers. They will coexist within the DOM however look fully totally different within the UI.

Shifting to actual content material

Including match content material

Within the demo beneath, I added extra content material and gadgets so we will discover a couple of particulars past the grid structure.

Have a look:

Spherical of 16

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Quarter-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Semi-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Closing

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Nothing particular right here, I simply added the groups, wrapped every two groups in a container (the match), and added distinctive colours for simpler rationalization.

Centering matches throughout rounds

Let’s heart the match gadgets vertically.

@container rounds (width > 680px) {
  .spherical {
    align-items: heart;
  }

  .finals {
    justify-content: heart;
  }
}

Spherical of 16

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Quarter-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Semi-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Closing

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

The issue with that is that the matches in numerous rounds should not aligned with one another, so if I would like to attract a line between the matches, it is going to look off-center.

I added a connector between the spherical 6 and spherical 4 matches. The center of the connector needs to be aligned with the center of the primary match in spherical 4.

Spherical of 16

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Quarter-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Semi-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Closing

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Centering the matches with align-items: heart just isn’t working right here. Let’s return to the earlier state. I added outlines to:

  • Begin and finish containers
  • Every match container

Spherical of 16

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Quarter-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Semi-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Closing

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

To make the centering work, we have to let every match take the obtainable area equally with its siblings. We are able to try this by setting flexbox on the .begin and .finish containers, then utilizing the flex property to distribute the area equally.

.begin,
.finish {
  show: flex;
  flex-direction: column;
}

.match {
  flex: 1;
  justify-content: heart;
  define: dashed 1px darkolivegreen;
  outline-offset: -2px;
}

Now the centering is sensible. Check out the next demo:

Spherical of 16

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Quarter-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Semi-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Closing

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Making it responsive

To take care of the structure on smaller sizes, we have to hold it trying like a hierarchy. At this stage, there isn’t a want to separate the spherical into two columns; we will hold it as one column.

.rounds {
  show: grid;
  grid-template-columns: repeat(4, 1fr);
}

It will make the rounds stream naturally, from left to proper (or from begin to finish when you desire logical properties).

Toggle flex: 1 and see how the gadgets can be centered vertically.

Spherical of 16

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Quarter-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Semi-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Closing

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Placing all of it collectively

The article’s fundamental focus was on the grid structure, however there nonetheless a lot to discover on this design. For instance, the right way to deal with the road connectors between the matches. For those who like me to write down about that, let me know on social media and I’ll contemplate it.

Spherical of 16

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Quarter-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Semi-finals

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Closing

🏴󠁧󠁢󠁥󠁮󠁧󠁿ENG

Study extra about CSS layouts

Constructing layouts is usually a difficult activity, specifically when you don’t know the core psychological mannequin of CSS layouts. You don’t have to fret about that anymore. I launched an interactive CSS structure course, and I referred to as it, The Format Maestro.

A screenshot of the Layout Maestro course landing page

Checkout The Format Maestro course and use the code fifa for $20 off. Obtainable for per week from the date of this text.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments