SypherTecSypherTec
PART 2 · 10 OF 126 MIN READUPDATED 6 AUG 2026

Flex Alignment: justify-content, align-items, and gap

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:

WHERE YOU LEFT OFF · HTML
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.
Untitled
RUN TO SEE YOUR PAGE

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.

THREE CARDS, PACKED AGAINST THE LEFT EDGE · HTML
Untitled
RUN TO SEE YOUR PAGE

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.

THE SAME THREE CARDS, SPREAD ACROSS THE ROW · HTML
Untitled
RUN TO SEE YOUR PAGE

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.

TWO CARDS, DIFFERENT HEIGHTS, NO ALIGN-ITEMS SET · HTML
Untitled
RUN TO SEE YOUR PAGE

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, TOLD TO SIT AT THEIR OWN HEIGHT · HTML
Untitled
RUN TO SEE YOUR PAGE

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.

YOUR REAL SKILLS LIST, SPREAD ACROSS THE PANEL · HTML
Untitled
RUN TO SEE YOUR PAGE

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.

YOUR REAL NAV, SPREAD ACROSS THE HEADER · HTML
Untitled
RUN TO SEE YOUR PAGE

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

index.html
<!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>
styles.css
.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:

ALIGN-ITEMS: SPACE-BETWEEN; CHANGES NOTHING · HTML
Untitled
RUN TO SEE YOUR PAGE

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 SET ON THE CARDS INSTEAD OF THE ROW · HTML
Untitled
RUN TO SEE YOUR PAGE

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.

  1. 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.
  2. In styles.css, add a new nav rule with display: flex;, justify-content: space-between;, align-items: center;, and gap: 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, so align-items: center changes nothing you can see here; it earns its keep when items differ in height, as in the demo above.
  3. In .skill-card, delete margin-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.
  4. In .skill-row, add justify-content: space-between; and gap: 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 on ul, so the first card will not sit flush with the panel's left edge.
  5. Break it on purpose: in your nav rule, delete justify-content: space-between; and change align-items: center; to align-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.
  6. Fix it: change align-items back to center, and add justify-content: space-between; back to the nav rule. Run it. Confirm the links return to their spread-out row.
TRY IT YOURSELF · HTML
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.
Untitled
RUN TO SEE YOUR PAGE

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.

QUIZ · 3 QUESTIONSCheck what stuckStart the quiz
PART 2 · 10 OF 12