본문으로 건너뛰기

주축 정렬

HTML·CSS 목차한 줄로 나란히: flex레슨 66 / 93

목차

justify-content는 주축에서 남는 자리를 어디에 둘지 정합니다. 남는 자리는 부모의 주축 길이에서 항목들이 차지한 길이를 뺀 나머지이고, 값에 따라 그 자리를 한쪽에 모으거나 항목 사이에 나눕니다.

항목을 한 줄에 놓아도 오른쪽에 자리가 남곤 합니다. 카드의 이름과 배지를 양 끝으로 떼거나, 머리글의 사이트 이름과 내비게이션을 양 끝에 두려면 그 남는 자리를 둘 사이에 넣어야 합니다. 그런데 값을 바꿔도 아무 일이 없을 때가 있습니다 — 나눌 자리가 없을 때입니다. 이 레슨에서는 남는 자리를 재는 법, 모으는 값 셋과 나누는 값 셋, 그리고 항목 하나만 끝으로 보내는 법을 봅니다.

그림 준비 중

1남는 자리 — 항목을 놓고 남은 주축의 길이

너비 240px인 상자에 너비 40px 항목 셋을 놓으면, 셋이 120px을 차지하고 주축(가로)에 120px이 남습니다.

<div class="box">
  <div>A</div>
  <div>B</div>
  <div>C</div>
</div>
.box {
  display: flex;
  width: 240px;
}

.box div {
  width: 40px;
  height: 40px;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .box의 justify-contentnormal
  • .box div:last-child의 오른쪽 끝128px

처음 값은 normal입니다. flex에서는 시작 쪽에 항목을 모으는 값 flex-start처럼 놓여, 남는 120px이 모두 C 뒤(128px부터 248px까지)에 있습니다.

2모으는 값 셋 — 남는 자리를 덩어리째 옮긴다

flex-start · center · flex-end는 항목 셋을 한 덩어리로 붙여 두고, 남는 자리를 끝 · 양쪽 · 앞으로 옮깁니다. 1절 상자에 값을 바꿔 넣으면 A의 왼쪽 자리가 이렇게 바뀝니다.

값남는 120pxA의 왼쪽 자리
flex-start모두 뒤에8px
center앞뒤 60px씩68px
flex-end모두 앞에128px

8px은 body의 바깥 여백입니다. 상자가 8px에서 시작하니, center면 앞에 60px을 두고 68px에서 A가 시작합니다.

3나누는 값 셋 — 남는 자리를 항목 사이에 나눈다

space- 값 셋은 항목을 떼어 놓고 남는 자리를 쪼개 나눕니다. 양 끝에 몫을 두는지가 셋을 가릅니다.

<div class="box">
  <div>A</div>
  <div>B</div>
  <div>C</div>
</div>
.box {
  display: flex;
  justify-content:
    space-between;
  width: 240px;
}

.box div {
  width: 40px;
  height: 40px;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .box div:first-child의 왼쪽 자리8px
  • .box div:nth-child(2)의 왼쪽 자리108px
  • .box div:last-child의 오른쪽 끝248px

space-between은 A를 시작 끝, C를 마지막 끝에 붙이고 남는 120px을 사이 두 곳에 60px씩 나눴습니다.

값양 끝 빈 자리사이 빈 자리
space-between060px
space-around20px40px
space-evenly30px30px

A의 왼쪽 자리는 body 바깥 여백 8px에 앞 끝 빈 자리를 더해 차례로 8 · 28 · 38px입니다.

셋 모두 같아지는 것은 항목 사이의 빈 자리이고, 항목의 자리가 아닙니다. 이 상자는 항목 너비가 같아 B가 한가운데에 놓였지만, 첫 항목과 끝 항목의 너비가 다르면 가운데 항목은 한가운데에서 비켜납니다.

예제

카드 제목 묶음에서 이름과 배지를 양 끝으로 뗍니다. 묶음 너비는 280px로 정했습니다.

<div class="recipe-card-head">
  <h2>떡볶이</h2>
  <span class="badge">한식</span>
</div>
.recipe-card-head {
  display: flex;
  justify-content:
    space-between;
  width: 280px;
}

h2 {
  margin: 0;
}
결과 화면
잰 값개발자 도구에서 본 값
  • h2의 왼쪽 자리8px
  • .badge의 오른쪽 끝288px

이름은 묶음 시작 끝(8px)에, 배지는 묶음 마지막 끝(8 + 280 = 288px)에 붙었습니다. 이름과 배지의 글자 너비가 얼마든, 남는 자리는 모두 둘 사이로 들어갑니다. 머리글의 사이트 이름과 내비게이션도 같은 값으로 양 끝에 둡니다.

자주 틀리는 곳

틀린 생각: space-between을 주면 항목은 언제나 양 끝으로 벌어진다.

<div class="box">
  <div>A</div>
  <div>B</div>
  <div>C</div>
</div>
.box {
  display: flex;
  justify-content:
    space-between;
  width: 240px;
}

.box div {
  width: 80px;
  height: 40px;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .box div:nth-child(2)의 왼쪽 자리88px

항목 셋이 80px씩, 모두 240px이라 상자를 다 채웠습니다. B는 A 바로 뒤(88px)에 붙어, flex-start일 때와 같습니다.

맞는 규칙: justify-content는 남는 자리를 옮길 뿐, 항목을 줄이거나 부모를 넓히지 않습니다. 남는 자리가 없으면 어느 값도 벌어지지 않습니다 — 항목이 남는 자리를 다 가져가는 flex: 1(gap과 flex: 1)을 받았을 때도 같습니다.

틀린 생각: space-around와 space-evenly는 같은 값이다.

둘 다 고르게 띄우니 이름만 다른 것 같습니다. 1절 상자에 두 값을 차례로 넣어 봅니다.

<div class="box">
  <div>A</div>
  <div>B</div>
  <div>C</div>
</div>
.box {
  display: flex;
  justify-content: space-around;
  width: 240px;
}

.box div {
  width: 40px;
  height: 40px;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .box div:first-child의 왼쪽 자리28px
.box {
  justify-content: space-evenly;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .box div:first-child의 왼쪽 자리38px

space-around는 A 앞이 20px, space-evenly는 30px입니다. around는 항목마다 양옆에 같은 몫(20px씩)을 붙여, 끝 빈 자리가 사이 빈 자리(40px)의 절반입니다. evenly는 끝과 사이 네 곳을 모두 같게(30px씩) 나눕니다.

맞는 규칙: 사이만 나누면 space-between, 항목 양옆에 같은 몫이면 space-around, 끝까지 모두 같게면 space-evenly입니다.

틀린 생각: 항목 하나만 끝으로 보내려면 justify-content를 바꾼다.

C 하나만 오른쪽 끝에 두고 싶어 flex-end를 주면, A · B · C가 한 덩어리로 오른쪽 끝에 모입니다. justify-content는 부모의 값이라 모든 항목에 한꺼번에 닿습니다. 한 항목만 옮기려면 그 항목에 margin-left: auto를 줍니다.

<div class="box">
  <div>A</div>
  <div>B</div>
  <div class="c">C</div>
</div>
.box {
  display: flex;
  width: 240px;
}

.box div {
  width: 40px;
  height: 40px;
}

.c {
  margin-left: auto;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .box div:nth-child(2)의 왼쪽 자리48px
  • .c의 왼쪽 자리208px

A · B는 시작 쪽에 그대로 있고, C만 오른쪽 끝(208 ~ 248px)으로 갔습니다. auto 바깥 여백이 남는 120px을 모두 C 앞에 받았습니다.

맞는 규칙: 남는 자리를 항목 하나 앞에 몰아줄 때는 그 항목의 margin-left: auto를 씁니다. justify-content는 항목 모두를 함께 옮깁니다.

틀린 생각: row에서 세로 가운데도 justify-content로 맞춘다.

높이 100px 상자의 세로 가운데에 '가'를 놓으려고 justify-content: center⁠를 줘 봅니다.

<div class="row">
  <div>가</div>
</div>
.row {
  display: flex;
  justify-content: center;
  width: 200px;
  height: 100px;
}

.row div {
  width: 40px;
  height: 40px;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .row div의 왼쪽 자리88px
  • .row div의 위 자리8px

'가'는 가로 가운데(88px)로 갔고, 세로는 위 끝(8px) 그대로입니다. row의 주축은 가로이고, 세로는 교차축이라 교차축 정렬의 align-items가 맡습니다.

맞는 규칙: justify-content는 주축만 맡습니다. 어느 쪽이 주축인지는 flex-direction이 정합니다(주축과 교차축).

확인 문제

1. 예제의 묶음 너비 280px을 240px로 줄였습니다. 배지의 오른쪽 끝은 몇 px이 될까요?

<div class="recipe-card-head">
  <h2>떡볶이</h2>
  <span class="badge">한식</span>
</div>
.recipe-card-head {
  display: flex;
  justify-content:
    space-between;
  width: 240px;
}

h2 {
  margin: 0;
}
  • ① 248px
  • ② 288px 그대로
  • ③ 이름 바로 옆으로 붙는다
힌트

space-between이 마지막 항목을 어디에 붙이는지 보고, 묶음이 몇 px에서 시작해 몇 px에서 끝나는지 셉니다.

정답

① 248px

결과 화면
잰 값개발자 도구에서 본 값
  • .badge의 오른쪽 끝248px
  • space-between은 마지막 항목을 부모의 마지막 끝에 붙입니다. 묶음은 8px에서 시작해 240px이니 248px에서 끝납니다.
  • ②는 배지가 제 자리를 지킨다고 본 것입니다. 배지의 자리는 부모 끝이 정합니다.
  • ③은 너비가 줄면 사이가 없어진다고 본 것입니다. 이름과 배지를 놓고도 자리가 남아, 그 자리가 둘 사이로 갑니다.

2. 머리글의 사이트 이름과 내비게이션을 양 끝에 두려 합니다. 주석은 배치를 짜는 세 걸음 가운데 둘입니다(셋은 자주 쓰는 세 모양에서 정리합니다). ____ 자리에 알맞은 값을 쓰세요.

<header class="site-header">
  <a href="index.html">
    레시피 노트
  </a>
  <nav>
    <a href="kimchi.html">
      김치볶음밥
    </a>
  </nav>
</header>
/* 1. 부모 정하기 */
.site-header {
  display: flex;
  /* 3. 남는 자리와 정렬 */
  justify-content: ____;
}
힌트

첫 항목은 시작 끝에, 마지막 항목은 마지막 끝에 붙는 값을 2절 · 3절 표에서 찾습니다.

정답

space-between

<header class="site-header">
  <a href="index.html">
    레시피 노트
  </a>
  <nav>
    <a href="kimchi.html">
      김치볶음밥
    </a>
  </nav>
</header>
/* 1. 부모 정하기 */
.site-header {
  display: flex;
  /* 3. 남는 자리와 정렬 */
  justify-content:
    space-between;
}
결과 화면폭 360px
잰 값개발자 도구에서 본 값
  • .site-header > a의 왼쪽 자리8px
  • nav의 오른쪽 끝352px

폭 360px 창에서 머리글은 8px부터 352px까지입니다. 사이트 이름이 시작 끝에, nav가 마지막 끝에 붙었습니다. flex-end면 둘이 함께 오른쪽에 모이고, space-around · space-evenly면 양 끝에도 빈 자리가 남습니다. 둘째 걸음(방향과 간격)은 처음 값 row 그대로라 비워 두었습니다.

3. 플로우 카페 메뉴판의 한 줄입니다. 메뉴 이름과 가격을 한 줄 양 끝에 두려고 했는데, 두 줄로 쌓였습니다. 무엇을 더해야 할까요?

<div class="item">
  <p>커피</p>
  <p>4000원</p>
</div>
.item {
  justify-content:
    space-between;
  width: 240px;
}
결과 화면
힌트

justify-content가 자리를 나눠 주는 상대는 무엇인지, 이 div의 자식이 지금 무엇으로 놓이는지 봅니다.

정답

.item에 display: flex;를 더합니다.

<div class="item">
  <p>커피</p>
  <p>4000원</p>
</div>
.item {
  display: flex;
  justify-content:
    space-between;
  width: 240px;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .item의 줄 수1
  • .item p:last-child의 오른쪽 끝248px
  • justify-content는 flex 항목 사이에 남는 자리를 나눕니다. display: flex가 없으면 .item은 일반 흐름이라 두 p는 블록으로 쌓이고, 이 선언은 오류 없이 아무 일도 하지 않습니다.
  • display: flex를 더하면 두 p가 항목이 되어 한 줄에 서고, 가격이 상자 끝(248px)에 붙습니다(브라우저 규칙 7).

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. hello.html의 body 안을 1절 상자 코드로, style 요소 안을 1절 CSS로 바꿉니다. .box 규칙에 justify-content 줄을 더하고 값을 flex-start · center · flex-end · space-between · space-around · space-evenly로 하나씩 바꿔 저장 · 새로고침합니다. 개발자 도구 Elements 패널에서 A 줄에 마우스를 올리면 페이지에서 A가 칠해집니다 — 2절 · 3절 표의 왼쪽 자리처럼 A가 옮겨 가는지 봅니다. 파일을 만들고 여는 법은 준비: VS Code와 작업 폴더에 있습니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

HTML·CSS 목차로