# CSS Flexbox and Grid: Build Real Layouts Without the Headache

Last time, we used `position` to pin a badge to a card and a button to the screen. But try building a whole page that way, with a header, a sidebar, and a row of cards, and you end up fighting pixel offsets that break on every screen size.

CSS has two tools built exactly for this: **Flexbox** and **Grid**. This blog is for beginners, and by the end you’ll know what each one does, when to pick which, and you’ll build a real page layout with them.

### The Big Idea

Both tools work the same way. You don’t move each child yourself. You tell the **parent** how to arrange its children, and the children follow. The parent is the **container**, and the children are the **items**. One line turns it on:

```css
.container {  
	display: flex;   /* or: display: grid; */
}
```

We’ll use this HTML throughout:

```html
<div class="container">  
	<div class="item">1</div>  
	<div class="item">2</div>  
	<div class="item">3</div>
</div>
```

And one small base block, so every box is visible. The container gets a coral outline, so you can always see its edges:

```css
body { 
	background: #1a1a1a; 
	color: #fff; 
}

.container { 
	border: 2px solid #ff6b4a; 
	padding: 10px; 
}

.item {  
	background: #262626;  
	border: 2px solid #4da3ff;  
	padding: 20px;
}
```

From here on, we only look at the lines that matter.

### Flexbox: Arranging Things in One Direction

Flexbox lays items out in **one line**, as a row or a column. Add one line, and the stacked boxes jump side by side:

```css
.container {  
	display: flex;
}
```

#### The two axes

Every flex container has two directions, and this idea makes everything else click:

1. **Main axis:** the direction items flow in (a row by default, left to right).
2. **Cross axis:** the direction across it (top to bottom).

![](https://cdn.hashnode.com/uploads/covers/6aa385803606a7bd7c205588/78789439-4f8b-48b0-ae1a-8f4c56ec7c21.png align="center")

#### justify-content: spacing along the main axis

```css
.container {  
	display: flex;  
	justify-content: space-between;
}
```

Common values are `flex-start`, `center`, `flex-end`, `space-between`, and `space-around`. With `space-between`, the first item hugs the left edge, the last hugs the right, and the rest spread out evenly. That’s exactly how a navbar with a logo on the left and links on the right is built.

![](https://cdn.hashnode.com/uploads/covers/6aa385803606a7bd7c205588/3c10436d-56b8-4d60-bfcc-139c4b36142d.png align="center")

#### align-items: alignment along the cross axis

```css
.container {  
	display: flex;  
	align-items: center;
}
```

This lines items up in the middle, vertically. Put both together, and you get the most famous trick in CSS, perfect centering:

```css
.container {
  display: flex;  
  justify-content: center;  
  align-items: center;  
  height: 300px;   /* needs room to center in */
}
```

#### gap and wrap

```css
.container {  
	display: flex;  
	gap: 16px;          /* space between items */  
	flex-wrap: wrap;    /* let items drop to the next line */
}
```

Without `flex-wrap`, items squeeze to stay on one line. With it, they move to a new line when they run out of space.

One warning: if you set `flex-direction: column`, the axes **swap**. `justify-content` then works vertically and `align-items` works horizontally. That trips up almost everyone once.

### Grid: Arranging Things in Rows and Columns

Flexbox handles one direction. **Grid** handles both at once, like a spreadsheet. You describe the columns, and items fall into the cells.

#### Columns and the fr unit

```css
.container {
  display: grid;  
  grid-template-columns: repeat(3, 1fr);  
  gap: 16px;
}
```

This makes **three equal columns**. Add six items, and you get two rows automatically, with no need to say how many rows you want.

`fr` stands for **fraction** of the available space. `1fr 1fr 1fr` means three equal shares, and `2fr 1fr` makes the first column twice as wide as the second. The `repeat(3, 1fr)` above is just a shortcut for writing `1fr` three times.

![](https://cdn.hashnode.com/uploads/covers/6aa385803606a7bd7c205588/95493b66-9c50-46f0-bc93-a04a60aed096.png align="center")

#### Spanning cells

Sometimes one item should be bigger, like a featured card. That rule goes on the **item**:

```css
.item:first-child {  
	grid-column: span 2;   /* takes two columns */
}
```

#### A grid that adapts by itself

This one line is the secret behind most responsive card galleries:

```css
.container {
  display: grid;  
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));  
  gap: 16px;
}
```

In plain words: “make as many columns as fit, each at least 200px wide, and share the leftover space.” On a wide screen you might get four columns, on a tablet two, and on a phone one, with no media query.

![](https://cdn.hashnode.com/uploads/covers/6aa385803606a7bd7c205588/b7247f28-ec55-47dc-8f00-3e49127ea9d2.png align="center")

### Flexbox or Grid?

A simple rule works well: **Flexbox is for one direction. Grid is for two.**

1. **Use Flexbox** for navbars, button groups, centering, or a single row of items.
2. **Use Grid** for page layouts, card galleries, and anything with rows and columns.

You’ll often use both together, so let’s do exactly that.

![](https://cdn.hashnode.com/uploads/covers/6aa385803606a7bd7c205588/5e2d7138-355a-41e3-8da2-ccd43aabae57.png align="center")

### Mistakes Almost Everyone Makes

1. **Putting flex properties on the items instead of the container.** `justify-content` and `align-items` go on the parent.
2. **Forgetting** `display: flex` **or** `display: grid`**.** Without it, nothing else works.
3. **Centering without a height.** `align-items: center` needs room to work with.
4. **Mixing up the axes after** `flex-direction: column`**.** They swap.
5. **Using** `position: absolute` **for layouts.** That’s exactly what these two tools replace.

### Wrapping Up

Flexbox and Grid share one idea: **let the parent arrange the children.** Flexbox arranges along one line, and Grid arranges in rows and columns. Learn `justify-content`, `align-items`, `gap`, and `grid-template-columns`, and you can already build most layouts on the web.
