Your Skills cards line up in a row now, but they still hug the left edge of their panel. The only spacing between them is the margin-right you added by hand. Your nav links do the same thing at the top of the page, clumped together instead of spread across it. This lesson introduces two properties that decide where flex items sit inside their row: justify-content and align-items. A third property, gap, gives you a cleaner way to space them than margin.
The concept
Here is your page as it stands. Run it:
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.
The "where you left off" demos show the placeholder version of the page. Your own page, with your real content, is safe in the exercise below.
A flex container arranges its items along two directions at once. The main axis is the direction items travel, left to right by default in a row. Run these three cards inside a container wider than they need.
The grey background shows the full width of the row. The three cards pack themselves against the left edge, leaving empty space on the right. That empty space sits along the main axis. By default, nothing tells the container what to do with it. Watch one property change that. Run it.
Same three cards, same container width. This time they spread out: one at the start, one in the middle, one at the end. The leftover main-axis space splits evenly between them. The only change was justify-content: space-between on the row.
The other direction, perpendicular to the main axis, is the cross axis: top to bottom in a row. Run these two cards, one holding more text than the other, with no alignment property set at all.
Both cards show the same height, even though one holds far more text. Flex items stretch to fill the container's cross axis by default. The shorter card's white background stretches down to match the taller one, hiding the real difference in content. Now tell the row to stop stretching them. Run it.
The same two cards, same text, this time each sized to its own content. align-items: flex-start lines both cards up at the top of the cross axis instead of stretching them to match, and the real height difference becomes visible.
Apply both ideas to your real Skills list. Run it.
The three skills you have styled since the last lesson now spread evenly across the grey panel. gap opens a clean space between each card instead of the margin-right you set by hand.
Your nav takes the same treatment. Run it.
About sits at the far left, Contact at the far right, and Skills in the middle. The row spreads across the full width of the header instead of clumping together at the start.
The syntax
justify-content sets how a flex container distributes space along the main axis.
.row {
justify-content: space-between;
}Until you set it, a flex container packs items at the start of the row. space-between puts the leftover space between items instead, leaving none at the outer edges.
align-items sets how a flex container positions items along the cross axis.
.row {
align-items: center;
}Its default behavior stretches every item to fill the container's cross-axis size. Items of different content lengths can look the same height until you change that, by setting align-items to flex-start, center, or flex-end.
gap sets the space a flex container leaves between its own items, without adding any space before the first item or after the last one.
.row {
gap: 1rem;
}gap only means something on the container. It has no effect written on one of the items instead.
A minimal working example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Flex alignment</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="row">
<div class="card">HTML</div>
<div class="card">CSS</div>
<div class="card">JavaScript</div>
</div>
</body>
</html>.row {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.card {
background-color: rgb(237, 242, 244);
padding: 1rem;
}Three cards, spread across the row and aligned along its cross axis. The gap between them stays fixed no matter how much leftover space justify-content has to work with.
Common mistakes
You write align-items: space-between; on your nav, expecting the links to spread apart. They stay clumped at the left, with no error anywhere to warn you. Run it:
space-between is a valid value for justify-content, the main-axis property, but not for align-items, the cross-axis one. The browser treats the whole declaration as invalid and ignores it, falling back to align-items's default as though the line never existed. Main axis and cross axis take different values because they answer different questions: where along the row, against where up and down.
You add gap: 1rem; to your card items, expecting space to open up between them. The cards sit flush against each other, unchanged. Run it:
gap belongs to the flex container, describing the space to leave between that container's own children. Written on .card, one of the children, there is nothing beneath it to space out. The rule has no children of .card to arrange, so it does nothing at all. Move gap to the row, the flex container, for it to take effect.
Try it yourself
Your nav links sit close together, and your Skills cards space themselves apart with a margin-right left over from the last lesson. Spread both out with the properties from this lesson. The nav sits in the header above the fold. After each Run that asks about the skill cards, scroll the preview to Skills if you do not see them yet.
- Run the starting code below. Confirm your nav links sit close together at the top left of the header. Scroll the preview to Skills if you do not see it yet. Confirm your three skill cards sit near the left edge of the grey panel too.
- In
styles.css, add a newnavrule withdisplay: flex;,justify-content: space-between;,align-items: center;, andgap: 1rem;. Run it. Confirm About now sits at the far left of the header and Contact at the far right, with Skills between them. The row spreads across the full width of the page. Your links are all the same height, soalign-items: centerchanges nothing you can see here; it earns its keep when items differ in height, as in the demo above. - In
.skill-card, deletemargin-right: 1rem;. Run it. Scroll to Skills. Confirm the three skill cards now sit flush against each other, with no space between them at all. - In
.skill-row, addjustify-content: space-between;andgap: 1rem;. Run it. Scroll to Skills. Confirm the three cards spread across the grey panel again, with a clean, even gap between each one. The list still keeps a little indent on the left from the browser's default padding onul, so the first card will not sit flush with the panel's left edge. - Break it on purpose: in your
navrule, deletejustify-content: space-between;and changealign-items: center;toalign-items: space-between;. Run it. Confirm the three links snap back together at the left edge of the header, exactly like your very first Run. A spacing rule still sits right there in your CSS, and it still changes nothing. - Fix it: change
align-itemsback tocenter, and addjustify-content: space-between;back to thenavrule. Run it. Confirm the links return to their spread-out row.
▸WHAT'S ALREADY IN THIS PAGE
New here? This starter already carries the standard HTML frame. You do not need to change it to do the exercise — each piece is taught in its own lesson.
<!DOCTYPE html>— Tells the browser to use modern rendering rules. Taught in lesson 2.<html> … </html>— The root element that wraps the whole document. Taught in lesson 2.lang="en"— Sets the page's language. Taught in lesson 6.<head>— Holds information about the page; nothing in it is drawn on screen. Taught in lesson 2.<meta charset="UTF-8" />— Sets how the browser decodes the text. Taught in lesson 6.<title>— Sets the browser-tab text. Taught in lesson 2.<body>— Holds everything a visitor actually sees. Taught in lesson 2.
Your nav spreads across the header, and your Skills cards space themselves evenly with one property instead of a margin trick. The next lesson steps back from individual rows. It looks at the page as a whole: a centered column with consistent space from section to section.