CodingBanana
CodingBanana
CSS Fundamentals

CSS Grid

8 min read📖 Intermediate
CSS Grid is a two-dimensional layout system that places elements into rows and columns at the same time. Where Flexbox handles a single row or column, Grid handles the full layout — perfect for card grids, page layouts, and dashboards.

Let me ask you something.

You just learned Flexbox. And it is amazing. But have you noticed that Flexbox works really well in one direction at a time — either a row or a column?

What if you want to build something that has both rows and columns at the same time? Like a grid of movie thumbnails that lines up perfectly both horizontally and vertically. Or a full page layout with a sidebar on the left and content on the right. Or a dashboard with cards arranged in a structured pattern.

That is where CSS Grid comes in.

Flexbox is one dimensional. It handles either a row or a column. Grid is two dimensional. It handles rows and columns at the same time.

They are not competitors. They work together. Flexbox for smaller components like navbars and forms. Grid for bigger layouts like full pages and card grids.

Let us learn how it works.

How Grid Works

Just like Flexbox, Grid works on a parent and children relationship.

You have a container. You turn it into a grid container. All the children inside automatically become grid items and you place them into rows and columns.

You turn a container into a grid by writing one line.

Right now nothing looks different from a normal block layout. That is because we have not told Grid how many columns we want yet. The cards just stack on top of each other.

That is what we do next.

grid-template-columns

This is the most important Grid property. It defines how many columns your grid has and how wide each one is.

Now we have a proper grid. Three columns, each 160px wide. The five cards flow into the grid automatically — three in the first row and two in the second.

Here is what is happening line by line.

display: grid — turns the container into a grid. Without this nothing works.

grid-template-columns: 160px 160px 160px — this is saying make three columns and each one should be 160px wide. The number of values you write is the number of columns you get. Three values means three columns.

gap: 12px — adds 12px of space between every row and every column at the same time. Clean and simple.

The cards do not need a width anymore because the column width controls how wide each cell is. The card just fills whatever column it lands in.

Using repeat()

Writing 160px three times works fine for three columns. But what if you want five columns? Or ten? Typing the same value over and over gets tedious fast.

CSS Grid has a shortcut called repeat().

Exactly the same result as before. But much cleaner to write.

repeat(3, 160px) — the first number is how many times to repeat. The second value is the size. So repeat(3, 160px) means make three columns each 160px wide. If you wanted five columns you would write repeat(5, 160px). Simple.

💡

You will use repeat() constantly in Grid. Once you know it you will never go back to typing column widths manually. It is just cleaner and faster.

The fr Unit

So far we have used fixed pixel widths for columns. But what if you want the columns to share the available space evenly without worrying about exact pixel values?

That is what the fr unit is for. fr stands for fraction. It divides the available space into equal parts.

Now the three columns each take up one third of the available space. If the container is 900px wide each column becomes 300px. If the container is 600px wide each column becomes 200px. It adjusts automatically.

repeat(3, 1fr) — make three columns and divide the available space into three equal fractions. Each column gets one fraction which is one third of the total width.

The difference comes when you mix values.

Now the first column is twice as wide as the other two. The available space is split into four total fractions — two for the first column and one each for the second and third.

2fr 1fr 1fr — there are four total fractions to share. The first column gets two of them so it takes up half the space. The second and third columns each get one fraction so they each take up a quarter. The first card looks noticeably wider and the other two are the same size.

💡

The fr unit is one of the most useful things Grid introduced. It removes all the math from building equal column layouts. Instead of calculating percentages just use 1fr for every column and they all share the space equally. Clean, flexible, and responsive by nature.

grid-template-rows

Just like you define columns you can also define rows. This controls how tall each row is.

grid-template-columns: repeat(3, 1fr) — three equal columns sharing the full width.

grid-template-rows: 100px 100px — two rows each exactly 100px tall. The first value controls the first row and the second value controls the second row.

Notice the cards no longer need a fixed height — the row height controls that for them. The cards just fill the cell they land in.

In most real projects you will define columns but leave rows to size themselves automatically based on the content inside. grid-template-rows is more useful when you need specific row heights like a page layout with a fixed header height.

gap in Grid

gap controls the space between grid items. One value adds the same space between all rows and columns. Two values let you set row gap and column gap separately.

gap: 16px 8px — the first value is the row gap so there is 16px of space between each row of cards. The second value is the column gap so there is only 8px of space between cards in the same row. More breathing room vertically than horizontally.

Spanning Columns and Rows

Sometimes you want one item to take up more than one column or more than one row. Like a featured movie that is twice as wide as the others.

You do this with grid-column and grid-row on the item itself.

The first movie card is now twice as wide as the others. It stretches across two columns while the rest sit in their normal single column cells.

grid-column: span 2 — this is on the featured card not the container. It tells that specific card to stretch across two columns instead of just one. The other cards automatically flow around it filling the remaining space.

You can do the same for rows using grid-row: span 2 to make a card twice as tall.

💡

Spanning is perfect for featured content. A hero movie card that is bigger than the rest immediately draws the eye. You see this pattern constantly on streaming platforms, news sites, and portfolio pages. One big item, several smaller ones — Grid makes this effortless.

Building the Netflix Clone

Now let us add a proper movie grid section to our Netflix clone. Below the horizontal scrolling row we will add a grid section showing all five movies in a clean two dimensional layout with a featured card spanning two columns.

Here is what is happening in the full clone.

The navbar uses display: flex with justify-content: space-between so the logo sits on the far left and the Sign In button on the far right. align-items: center keeps both vertically centered on the same line.

The hero uses display: flex with flex-direction: column so the heading, paragraphs, and form stack on top of each other. align-items: center and justify-content: center put everything in the middle both horizontally and vertically. The form inside also uses display: flex so the input and button sit side by side.

The Trending Now row uses display: flex with overflow-x: auto so cards sit in a horizontal row and scroll sideways when there are too many to fit.

The Top Picks grid uses display: grid with repeat(3, 1fr) for three equal columns. The featured card uses grid-column: span 2 to stretch across the first two columns making it stand out as the hero movie. The remaining cards fill the rest of the grid automatically.

The page now has a navbar, a full screen hero, a horizontal scrolling row, and a two dimensional grid. That is a real Netflix-style layout built entirely with what you have learned so far.

In the next lesson I am going to show you CSS Position — how to take elements out of the normal flow and place them exactly where you want on the page. Fixed navbars, floating buttons, overlays — it all comes from position. Come on in.

Learn about CSS Positioning →

Have anything to say about this lesson?

Your feedback helps improve these tutorials. If something was confusing or missing, let us know.

We don't currently reply to feedback — but if we add that feature in the future, we'll reach out to you.