본문으로 건너뛰기

단원 연습 문제

HTML·CSS 목차격자로 배치: grid문제 13개

13단원 '격자로 배치: grid'의 다섯 레슨에서 10문제를 내고, 2 · 9 · 11단원에서 3문제를 섞었습니다. 앞 단원 문제가 어느 레슨인지는 정답을 펼치면 보입니다. 값이나 기호, 고친 줄은 종이에 끝까지 쓴 뒤 정답을 펼치세요. 막히면 정답 앞의 힌트를 먼저 펼칩니다. 점수는 매기지 않습니다.

결과를 묻는 문제의 결과 화면과 잰 값은 정답을 펼치면 보입니다. 열 너비와 열 수는 종이에 셈을 적어 풀고, 정답의 셈 표와 견주어 보세요. 컴퓨터가 있으면 문제의 HTML과 CSS를 파일로 저장해 브라우저로 열고, 개발자 도구 Computed 창에서 값을 맞춰 봅니다. Elements 패널에서 격자 요소 줄 끝의 grid 표시를 누르면 열 경계선이 겹쳐 보입니다. 글꼴 크기를 '크게'로 바꾼 브라우저에서 잰 값은 그렇게 밝힙니다. 결과는 모두 크롬 기준입니다.

이 단원을 이미 안다면 1 · 3 · 4 · 6 · 8 · 9번을 먼저 풀어 보세요. 건너뛸지 볼 때는 힌트를 펴지 않고 풉니다. 다 맞히면 이 단원은 건너뛰어도 됩니다. 틀린 문제와 힌트를 펴고 맞힌 문제는 정답 끝의 '다시 볼 레슨'으로 갑니다. 끝의 두 문제(12 · 13번)는 직접 만들어 보는 문제라, 건너뛸지 가릴 때는 풀지 않아도 됩니다. 11번까지 풀고 쉬었다가 12번부터 이어 풀어도 됩니다. ⟨컴퓨터⟩가 붙은 문제는 컴퓨터에서 파일을 만들어 풉니다. 폰으로만 본다면 그 문제 끝의 폰 물음 하나로 대신합니다.

문제 1

플로우 카페 메뉴판을 세 칸 격자로 놓았습니다. 첫 칸 '음료' 안에는 음료 이름 목록이 하나 더 들어 있습니다. 격자 칸에 한 칸씩 놓이는 요소(grid 항목)를 모두 고르세요. 기호를 다 쓰세요.

<ul class="menu">
  <li>
    음료
    <ul>
      <li>식혜</li>
      <li>홍차</li>
    </ul>
  </li>
  <li>디저트</li>
  <li>샌드위치</li>
</ul>
.menu {
  display: grid;
  grid-template-columns:
    repeat(3, 1fr);
  gap: 12px;
  padding: 0;
  list-style: none;
}
  • ㉠ 안쪽 ul
  • ㉡ li 음료
  • ㉢ li 식혜
  • ㉣ li 홍차
  • ㉤ li 디저트
  • ㉥ li 샌드위치
힌트

display: grid가 걸린 요소에 표시하고, 나무를 그려 여섯 요소가 각각 무엇 안에 드는지 적어 보세요.

힌트 둘

격자는 그 요소의 직계 자식만 칸에 놓습니다. 자식이 무엇을 품었는지는 따지지 않습니다.

정답

㉡ ㉤ ㉥ — 바깥 목록의 직계 자식 li 셋입니다.

결과 화면
잰 값개발자 도구에서 본 값
  • .menu > li의 고른 글음료 · 디저트 · 샌드위치
  • .menu의 열 수3
  • .menu ul의 열 수1
  • display: grid는 .menu에 걸렸고, 격자 칸에 놓이는 것은 그 직계 자식 li 셋입니다 — 세 열에 하나씩 놓였습니다(브라우저 규칙 7).
  • ㉢ ㉣은 .menu에서 보면 손자입니다. '음료' 칸 안에서 보통 목록처럼 위아래로 쌓였습니다.
  • ㉠ 안쪽 ul도 '음료' li의 자식이라 칸을 따로 받지 않습니다.
  • ㉡ ~ ㉥을 다 골랐다면 격자가 그 안의 모든 li에 닿는다고 본 것입니다(flex가 후손까지라는 생각과 같은 뿌리 — grid도 같습니다).
  • ㉢ ㉣ ㉤ ㉥을 골랐다면 목록을 품은 '음료' 칸은 항목이 아니라고 본 것입니다. 항목은 무엇을 품었든 직계 자식입니다.

다시 볼 레슨: flex 여러 줄과 grid · flex는 부모에

문제 2

음악 동아리 공지 칸 셋을 세 열 격자로 놓으려 했는데, 첫 칸의 닫는 태그를 빠뜨렸습니다. (가) 격자 칸에 놓이는 항목은 몇 개일까요? 숫자만 쓰세요. (나) '공연 연습' 칸은 '정기 회의' 칸의 오른쪽과 아래 가운데 어디에 놓일까요?

<div class="notes">
  <div>신입 모집
  <div>정기 회의</div>
  <div>공연 연습</div>
</div>
.notes {
  display: grid;
  grid-template-columns:
    repeat(3, 1fr);
  gap: 12px;
}
힌트

닫는 태그를 하나씩 짝지어, 브라우저가 짓는 나무를 종이에 그려 보세요. 그다음 .notes의 자식이 몇인지 셉니다.

힌트 둘

브라우저는 빠진 닫는 태그를 오류 없이 채워 넣지만, 그 자리는 내가 바란 곳이 아닐 수 있습니다. 첫 div가 어디에서 닫히는지 보세요.

정답

(가) 1 · (나) 아래

결과 화면
잰 값개발자 도구에서 본 값
  • .notes > div의 고른 글신입 모집
  • .notes > div > div:first-child의 왼쪽 자리8px
  • .notes > div > div:last-child의 왼쪽 자리8px
  • 첫 div에 닫는 태그가 없어, 브라우저는 뒤의 두 div를 그 안에 든 것으로 고쳐 짓습니다. 마지막 </div>는 '신입 모집' 칸을 닫고, .notes는 문서 끝에서 닫힙니다(브라우저 규칙 2).
  • 격자는 고쳐 지은 나무의 직계 자식만 칸에 놓습니다. .notes의 자식은 '신입 모집' 칸 하나라 첫 열 하나만 차지하고, '정기 회의' · '공연 연습'은 그 안에서 위아래로 쌓입니다(브라우저 규칙 7).
  • 흔한 오답은 (가) 3 · (나) 오른쪽입니다. 브라우저가 빠진 닫는 태그를 '신입 모집' 바로 뒤에 채운다고 본 것입니다. 브라우저는 내 뜻을 모르니, 뒤에 오는 닫는 태그로 차례대로 닫습니다.
  • 칸이 하나도 안 그려진다고 봤다면 틀린 곳에서 브라우저가 멈춘다고 본 것입니다(틀리면 멈춘다는 생각). 오류 메시지 없이 고쳐 지은 나무로 끝까지 그립니다.

다시 볼 레슨: 요소 안의 요소 · flex 여러 줄과 grid

문제 3

레시피 노트 김치볶음밥 페이지 아랫부분을 세 칸으로 나눴습니다. 가운데 '만드는 법' 칸의 너비는 몇 px일까요? 숫자만 쓰세요.

<div class="parts">
  <div>재료</div>
  <div>만드는 법</div>
  <div>팁</div>
</div>
.parts {
  display: grid;
  grid-template-columns:
    1fr 2fr 1fr;
  gap: 20px;
  width: 260px;
}
힌트

세 칸의 fr 값을 더해 모두 몇 몫인지부터 적어 보세요.

힌트 둘

fr은 열 사이 간격을 먼저 뺀 남는 폭을 나눕니다.

정답

110입니다.

결과 화면
잰 값개발자 도구에서 본 값
  • .parts div:nth-child(2)의 너비110px
  • .parts div의 너비55px
걸음셈값
1. 간격 빼기260 − 20 × 2220
2. 한 몫몫 1 + 2 + 1 = 4 → 220 ÷ 455
3. 가운데 칸55 × 2110
  • 열이 셋이면 사이 간격은 둘입니다. fr은 그 간격 40px을 먼저 빼고 남은 220px을 몫대로 나눕니다(브라우저 규칙 7).
  • 흔한 오답은 130입니다. fr이 간격까지 넣은 260px을 나눈다고 본 것입니다(260 ÷ 4 × 2).
  • 120은 간격을 하나만 뺀 것입니다. 간격은 열과 열 사이마다 하나씩, 열 수보다 하나 적습니다.

다시 볼 레슨: 열 만들기

문제 4

형광펜처럼 노랗게 칠하는 mark 둘을 같은 폭으로 나란히 놓으려고 격자를 만들었습니다. 결과 화면은 어떻게 보일까요? 보기 셋 가운데 고르세요.

<div class="g">
  <mark>가</mark><mark>나</mark>
</div>
.g {
  display: grid;
  grid-template-columns:
    repeat(2 1fr);
}
힌트

.g 규칙의 두 선언을 하나씩 보고, 브라우저가 알아듣지 못해 버리는 선언이 있는지 표시해 보세요.

힌트 둘

repeat() 괄호 안의 두 값 사이에 무엇이 와야 하는지 보세요. 버려지는 것이 선언 하나인지 규칙 전체인지도 가릅니다.

정답

② — 노란 띠 둘이 위아래로 쌓입니다.

결과 화면
  • repeat(2 1fr)은 개수 뒤 쉼표가 빠져 브라우저가 알아듣지 못하는 값이라, grid-template-columns 선언째 버립니다(브라우저 규칙 4). 같은 규칙의 display: grid는 그대로 먹어 .g는 격자이고, 열을 정한 선언이 없으니 한 열입니다. 두 mark는 격자 항목이 되어 열 폭만큼 넓은 띠로 한 줄씩 놓입니다.
  • ①은 브라우저가 빠진 쉼표를 채워 읽는다고 본 것입니다. HTML은 틀려도 고쳐 짓지만, CSS는 알아듣지 못한 선언을 버립니다.
  • ③은 선언 하나 때문에 규칙 전체가 버려진다고 본 것입니다(CSS도 멈춘다는 생각). 규칙째 버려졌다면 mark는 글자만큼 칠한 채 한 줄에 붙어 놓입니다.

다시 볼 레슨: 열 만들기 · 규칙의 모양

문제 5

사진 동아리 앨범 페이지입니다. 앨범 목록에 클래스 셋을 붙였고, 규칙 셋이 모두 이 목록의 열을 정합니다. 이 목록은 몇 열일까요? 숫자만 쓰세요.

<ul class="album small wide">
  <li>봄 출사</li>
  <li>여름 바다</li>
  <li>가을 단풍</li>
</ul>
.album.wide {
  grid-template-columns:
    repeat(3, 1fr);
}

.album.small {
  grid-template-columns: 1fr;
}

.album {
  display: grid;
  grid-template-columns:
    repeat(2, 1fr);
}
힌트

grid-template-columns⁠를 정하는 선언 셋을 손 점수판에 적고, 출처 · 명시도 · 차례 칸을 왼쪽부터 견줘 보세요.

정답

1입니다.

결과 화면
잰 값개발자 도구에서 본 값
  • .album의 열 수1
속성선언출처명시도차례이긴 값
grid-template-columns.album.small · 1fr우리 CSS0-2-021fr
.album.wide · repeat(3, 1fr)우리 CSS0-2-01
.album · repeat(2, 1fr)우리 CSS0-1-03

차례 칸은 규칙 차례(.album.wide 1 · .album.small 2 · .album 3)이고, 줄은 명시도의 점수판처럼 이긴 선언부터 적었습니다 — 코드 차례로 적어도 칸의 값이 같으면 맞습니다.

  • 셋은 출처가 같습니다. 명시도에서 .album(0-1-0)이 먼저 떨어집니다 — 맨 뒤에 썼어도 집니다. 남은 둘은 0-2-0으로 같아 차례로 갈리고, 뒤에 쓴 .album.small이 이깁니다(브라우저 규칙 5).
  • display: grid는 .album 규칙에만 있어 그대로 닿습니다. 이기고 지는 것은 같은 속성끼리입니다.
  • 흔한 오답은 2입니다. 나중에 쓴 규칙이 늘 이긴다고 본 것입니다(뒤가 늘 이긴다는 생각).
  • 3은 HTML class 값에서 맨 뒤에 적은 wide가 이긴다고 본 것입니다. class 값 안 이름의 차례는 겨룸에 들지 않습니다 — 차례 칸은 CSS에 쓴 차례입니다.

다시 볼 레슨: 명시도 · 나중에 쓴 규칙

문제 6

플로우 카페의 원두 카드를 들어가는 만큼 열로 놓았습니다. 목록 폭은 440px입니다. (가) 열은 몇 개일까요? (나) 칸 하나의 너비는 몇 px일까요? (다) 목록 폭을 몇 px 이상으로 넓히면 세 열이 될까요? 숫자만 쓰세요.

<ul class="beans">
  <li>에티오피아</li>
  <li>케냐</li>
  <li>콜롬비아</li>
  <li>과테말라</li>
</ul>
.beans {
  display: grid;
  grid-template-columns: repeat(
    auto-fill,
    minmax(140px, 1fr)
  );
  gap: 12px;
  width: 440px;
  padding: 0;
  list-style: none;
}
힌트

열을 하나씩 늘려 가며 열 최소 폭 몇 개가 목록 폭 440 안에 드는지 적어 보세요.

힌트 둘

열과 열 사이마다 간격이 하나씩 낍니다. 열 최소 폭과 간격을 함께 더해 440과 견주세요.

정답

(가) 2 · (나) 214 · (다) 444

결과 화면폭 480px
잰 값개발자 도구에서 본 값
  • .beans의 열 수2
  • .beans li의 너비214px
열 수셈440 안에 드나
2140 × 2 + 12292 — 든다
3140 × 3 + 12 × 2444 — 안 든다
  • 들어가는 열은 둘입니다. 남는 폭은 1fr로 나눠 칸 하나가 (440 − 12) ÷ 2 = 214px입니다(브라우저 규칙 7).
  • 세 열이 되려면 열 최소 폭 셋과 간격 둘이 다 들어가야 합니다 — 444px부터입니다. 아래는 목록 폭만 444px, 443px로 바꿔 잰 것입니다.
.beans {
  width: 444px;
}
결과 화면폭 480px
잰 값개발자 도구에서 본 값
  • .beans의 열 수3
  • .beans li의 너비140px
.beans {
  width: 443px;
}
결과 화면폭 480px
잰 값개발자 도구에서 본 값
  • .beans의 열 수2
  • 흔한 오답은 (가) 3 · (다) 420입니다. 간격을 빼고 440 ÷ 140으로 셈한 것입니다. 열 사이마다 간격이 끼니 함께 셉니다.

다시 볼 레슨: 들어가는 만큼 열 만들기

문제 7

레시피 목록 카드 격자의 열 최소 폭을 글자 크기 설정을 따르게 rem으로 옮기려 합니다. 목록 폭은 520px입니다.

.recipe-list {
  display: grid;
  grid-template-columns: repeat(
    auto-fill,
    minmax(240px, 1fr)
  );
  gap: 16px;
  width: 520px;
}

(가) 글자 크기 설정이 처음 그대로일 때 크기가 지금과 같도록 minmax(____, 1fr) 자리를 rem으로 채우세요. (나) 그렇게 옮긴 뒤 글꼴 크기를 '크게'로 바꾼 브라우저에서 열은 몇 개일까요? 숫자만 쓰세요.

힌트

1rem이 처음 설정과 '크게'에서 각각 몇 px인지 적고, 두 경우의 열 최소 폭으로 열 수를 셈해 보세요.

정답

(가) 15rem · (나) 1

결과 화면은 지금 이 브라우저의 설정대로 그려지고, 잰 값은 '크게'에서 잰 값입니다.

<ul class="recipe-list">
  <li>김치볶음밥</li>
  <li>계란말이</li>
  <li>된장찌개</li>
</ul>
.recipe-list {
  display: grid;
  grid-template-columns:
    repeat(
      auto-fill,
      minmax(15rem, 1fr)
    );
  gap: 16px;
  width: 520px;
  padding: 0;
}
결과 화면폭 560px
잰 값개발자 도구에서 본 값
  • .recipe-list의 열 수1
  • .recipe-list li의 너비520px
  • (가) 처음 설정에서 1rem은 16px이라 240 ÷ 16 = 15입니다. 처음 설정에서는 240px과 같아 두 열입니다(240 × 2 + 16 = 496).
  • (나) '크게'에서 1rem은 20px이라 열 최소 폭이 300px이 됩니다. 두 열이면 300 × 2 + 16 = 616으로 520을 넘어, 한 열입니다. 글자가 커진 만큼 카드도 넓게 잡혀 열이 줄었습니다.
  • (나)에서 흔한 오답은 2입니다. rem으로 옮긴 뒤에도 열 최소 폭이 240px 그대로라고 본 것입니다 — 그대로인 쪽은 px로 적은 값입니다.
  • (가)에서 단위만 바꾼 240rem은 처음 설정에서 3840px이라, 어느 화면에서도 한 열이 화면 밖으로 넘칩니다.

다시 볼 레슨: 글자 크기는 rem · 들어가는 만큼 열 만들기

문제 8

밴드 동아리 게시판을 네 열 격자로 놓고, '대회 안내' 칸만 세 열을 차지하게 했습니다. (가) 첫 줄에 놓이는 칸을 모두 고르세요. 기호를 다 쓰세요. (나) 결과 화면은 몇 줄일까요?

<div class="board">
  <div>출석</div>
  <div>일정</div>
  <div class="big">대회 안내</div>
  <div>연습실</div>
  <div>장비</div>
</div>
.board {
  display: grid;
  grid-template-columns:
    repeat(4, 1fr);
  gap: 8px;
}

.board div {
  height: 32px;
  background-color: #d2d2d7;
}

.big {
  grid-column: span 3;
}
  • ㉠ div 출석
  • ㉡ div 일정
  • ㉢ div 대회 안내
  • ㉣ div 연습실
  • ㉤ div 장비
힌트

네 칸짜리 줄을 종이에 그리고, HTML 차례대로 한 칸씩 채워 보세요. '대회 안내' 차례에서 그 줄에 남은 칸이 몇 개인지 셉니다.

힌트 둘

격자는 항목을 HTML 차례대로 다음 자리에 놓습니다. 남은 칸이 모자라면 다음 줄로 가고, 앞에 비운 칸으로 되돌아가지 않습니다.

정답

(가) ㉠ ㉡ · (나) 3

결과 화면
잰 값개발자 도구에서 본 값
  • .board div:nth-child(2)의 위 자리8px
  • .big의 위 자리48px
  • .board div:nth-child(4)의 위 자리48px
  • .board div:nth-child(5)의 위 자리88px
  • .board의 줄 수3
  • 출석 · 일정이 첫 줄의 두 칸을 채우면 남은 칸은 둘입니다. '대회 안내'는 세 칸이 필요해 첫 줄에 들지 못하고 둘째 줄 첫머리로 갑니다. 첫 줄의 뒤 두 칸은 빈 채로 남습니다(브라우저 규칙 7).
  • 연습실은 '대회 안내' 다음 자리인 둘째 줄 넷째 칸, 장비는 셋째 줄 첫 칸입니다.
  • ㉠ ㉡ ㉣ ㉤을 골랐다면 비워 둔 칸을 뒤 항목이 되돌아와 메운다고 본 것입니다. 격자는 HTML 차례대로 앞으로만 나아갑니다.
  • ㉠ ㉡ ㉢을 골랐다면 넓은 칸이 남은 두 칸에 맞춰 줄어든다고 본 것입니다. span 3은 늘 세 열을 차지합니다.

다시 볼 레슨: 칸 여러 개 차지하기

문제 9

짝마다 두 코드의 화면이 같은지 다른지 쓰세요. 다르면 어디가 다른지도 한 줄로 쓰세요. 셋 모두 같은 답이 나와도 됩니다.

(가)

<div class="g">
  <p>
    https://example.org/menu
  </p>
  <p>지도</p>
</div>
.g {
  display: grid;
  grid-template-columns:
    repeat(2, 1fr);
  width: 240px;
}
<div class="g">
  <p>
    https://example.org/menu
  </p>
  <p>지도</p>
</div>
.g {
  display: grid;
  grid-template-columns:
    repeat(2, minmax(0, 1fr));
  width: 240px;
}

(나)

<div class="g">
  <p class="top">제목</p>
  <p>사진</p>
  <p>설명</p>
</div>
.g {
  display: grid;
  grid-template-columns:
    1fr 1fr;
}

.top {
  grid-column: span 2;
}
<div class="g">
  <p class="top">제목</p>
  <p>사진</p>
  <p>설명</p>
</div>
.g {
  display: grid;
  grid-template-columns:
    1fr 1fr;
  grid-template-areas:
    "top top";
}

.top {
  grid-area: top;
}

(다)

<div class="g">
  <p>사진</p>
  <p>설명</p>
</div>
.g {
  display: grid;
  grid-template-columns:
    1fr 1fr;
}
<div class="g">
  <p>사진</p>
  <p>설명</p>
</div>
.g {
  display: flex;
}

.g p {
  flex: 1;
}
힌트

짝마다 바뀐 줄을 찾고, 그 줄이 열의 폭이나 항목의 자리를 바꾸는지 적어 보세요.

힌트 둘

(가)는 빈칸이 없는 긴 주소가 1fr 열에서 어떻게 되는지 보세요. (다)는 줄이 하나뿐일 때와 여럿일 때 flex와 grid가 어디서 갈리는지 떠올리세요.

정답

(가) 다르다 — 앞 코드는 주소가 든 첫 열이 넓고 '지도'가 오른쪽으로 밀린다 · (나) 같다 · (다) 같다

결과 화면(가) 첫째 코드
결과 화면(가) 둘째 코드
결과 화면(나) 첫째 코드
결과 화면(나) 둘째 코드
결과 화면(다) 첫째 코드
결과 화면(다) 둘째 코드
  • (가) 1fr 열은 안의 가장 긴 낱말보다 좁아지지 않습니다. 빈칸 없는 주소가 첫 열을 넓히고 둘째 열이 남은 폭을 갖습니다. minmax(0, 1fr)은 열 최솟값을 0으로 정해 두 열이 120px씩 같은 폭이고, 긴 주소는 칸 밖으로 삐져나옵니다.
  • (나) span 2로 첫 항목이 두 열을 차지하게 한 것과, 글자 지도의 첫 줄을 top 두 칸으로 둔 것은 같은 자리입니다. 이름이 없는 사진 · 설명은 HTML 차례대로 다음 줄의 두 칸에 놓입니다.
  • (다) 줄이 하나뿐이면 grid의 1fr 1fr과 flex의 flex: 1 둘은 같은 폭 두 칸입니다. 둘이 갈리는 것은 항목이 여러 줄로 넘어갈 때입니다 — flex는 줄마다 따로 나누고 grid는 모든 줄이 같은 열 경계를 씁니다.
  • (가) 같다는 fr이 긴 낱말이 있어도 폭을 똑같이 나눈다고 본 것입니다.
  • (나) 다르다는 글자 지도에 이름이 없는 항목은 놓이지 않는다고 본 것입니다.
  • (다) 다르다는 flex와 grid가 늘 다른 화면을 낸다고 본 것입니다.

다시 볼 레슨: 열 만들기 · 칸 여러 개 차지하기 · 영역에 이름 붙이기 · flex 여러 줄과 grid

문제 10

하고 싶은 일에 쓸 이름을 쓰세요.

  • (가) 격자에서 간격을 뺀 남는 폭을 나눠 갖는 몫의 단위
  • (나) 열 하나의 가장 좁은 폭과 가장 넓은 폭을 함께 정하는 CSS 함수
  • (다) 정한 폭의 열을 빈 열까지 남겨 두며 들어가는 만큼 만들라는 repeat() 안의 낱말
  • (라) 격자 항목을 글자 지도의 이름 자리에 놓는 CSS 속성
힌트

(가)는 1fr 2fr에 쓰인 단위, (다)는 카드 격자 틀의 열 선언 첫 조각, (라)는 항목 쪽 규칙에 쓰는 속성입니다.

정답

받는 답: (가) fr · (나) minmax() · (다) auto-fill · (라) grid-area

  • 같은 답으로 치는 꼴: (나) minmax만 써도, minmax(260px, 1fr)처럼 값을 넣어 써도 됩니다.
  • 틀리는 꼴 — (다) auto-fit도 들어가는 만큼 열을 만들지만, 항목이 모자라면 빈 열을 접어 항목을 넓힙니다. (라) grid-template-areas는 부모에 글자 지도를 그리는 속성이고, 항목을 그 이름 자리에 놓는 것은 항목의 grid-area입니다. grid-column은 이름이 아니라 열 몇 개를 차지할지 정합니다.

다시 볼 레슨: 열 만들기 · 들어가는 만큼 열 만들기 · 영역에 이름 붙이기

문제 11

여행 일정 페이지에서 지도를 왼쪽에 두 줄 높이로 세우고, 오른쪽에 날짜와 할 일을 위아래로 두려 했습니다. 그런데 지도가 오른쪽 아래 끝으로 밀려나고, 날짜와 할 일이 첫 줄에 나란히 놓였습니다. 개발자 도구에서 .trip을 골라 보니 Styles 창의 grid-template-areas 선언에 취소선과 경고 표시가 있습니다. CSS 몇 번 줄을 어떻게 고쳐야 할까요? 고친 줄을 쓰세요.

<div class="trip">
  <div class="map">지도</div>
  <p>셋째 날</p>
  <p>우산 챙기기</p>
</div>
.trip {
  display: grid;
  grid-template-columns:
    100px 1fr;
  grid-template-areas:
    "map ."
    ". map";
}

.map {
  grid-area: map;
}
결과 화면
힌트

찾는 차례대로 1번부터 지워 가세요. 4번에서 취소선이 그어진 선언의 글자 지도를 칸마다 종이에 옮겨 그려 봅니다.

힌트 둘

같은 이름은 붙어 있는 꽉 찬 직사각형이어야 합니다. 지도에서 map이 차지한 두 칸이 어떻게 이어져 있는지 보세요.

정답

받는 답: CSS 7번 줄을 "map .";으로 고칩니다 — 둘째 줄의 map도 첫째 열에 둡니다.

<div class="trip">
  <div class="map">지도</div>
  <p>셋째 날</p>
  <p>우산 챙기기</p>
</div>
.trip {
  display: grid;
  grid-template-columns:
    100px 1fr;
  grid-template-areas:
    "map ."
    "map .";
}

.map {
  grid-area: map;
}
결과 화면
잰 값개발자 도구에서 본 값
  • .trip의 grid-template-areas"map ." "map ."
  • .map의 왼쪽 자리8px
  • .trip p의 왼쪽 자리108px
  • .trip p:last-child의 왼쪽 자리108px

찾는 차례 4번에서 찾습니다.

  • 1번 — 지도 칸이 격자 안에서 움직였으니 CSS 파일은 닿았습니다.
  • 2번 — Elements 패널에 .trip 안의 세 요소가 다 있습니다.
  • 3번 — .trip을 고르면 Styles 창에 .trip 규칙이 보입니다.
  • 4번(닿았으면 알아들었나) — grid-template-areas에 취소선과 경고 표시가 있습니다. 지도를 칸마다 그리면 map이 왼쪽 위와 오른쪽 아래, 대각선 두 칸입니다. 같은 이름이 꽉 찬 직사각형이 아니면 브라우저는 지도 선언째 버립니다(브라우저 규칙 4).

지도가 버려지니 map이라는 이름 자리가 없습니다. .map은 이름 자리를 찾지 못해 정한 칸 밖, 오른쪽 아래에 새로 생긴 칸으로 밀려났습니다. 이름이 없는 두 p는 HTML 차례대로 첫 줄의 두 칸에 놓였습니다 — 날짜가 지도 자리에 선 까닭입니다.

다르게 고쳐도 되는 곳: 지도 대신 .map의 grid-area: map;을 grid-row: span 2;로 바꾸고 grid-template-areas 선언을 지워도 같은 화면입니다. 다만 고친 줄이 둘이 되고, 이 문제의 지도처럼 이름으로 자리를 읽는 길이 없어집니다.

  • 흔한 오답은 grid-template-areas 선언에 !important를 붙이는 것입니다. 버려진 값은 이기고 지기 전에 빠지니 그대로입니다.
  • 둘째 줄을 "map map";으로 고치면 map이 왼쪽 위 · 아래 두 칸과 오른쪽 아래 한 칸, ㄴ 자 모양이라 여전히 버려집니다.

다시 볼 레슨: 영역에 이름 붙이기 · 브라우저 기본 스타일과 Styles 창

문제 12 (만들어 보기)

영화 동아리 상영작 카드를 격자로 놓으려 합니다. 카드는 160px보다 좁아지지 않고, 열 수는 목록 폭에 맡기고, 카드 사이는 12px 띄웁니다. 하위 목표 주석만 남긴 틀의 …를 채우세요. 목록의 점과 왼쪽 안쪽 여백은 이미 지웠습니다.

<ul class="films">
  <li>우리들의 여름</li>
  <li>별을 찾는 아이</li>
  <li>마지막 상영</li>
  <li>바다로 가는 길</li>
</ul>
.films {
  padding: 0;
  list-style: none;
  /* 1. 목록에 grid */
  …
  /* 2. 열 최소 폭 */
  …
  /* 3. 간격 */
  …
}

나와야 할 결과는 둘입니다.

  • 창 폭 600에서 한 줄에 카드 셋이다.
  • 창 폭 360에서 한 줄에 카드 둘이고, 카드는 160px보다 넓다.
힌트

하위 목표 2는 카드 격자 틀의 열 선언입니다. repeat() 안에 '들어가는 만큼'과 '열 최소 폭'을 차례로 넣습니다.

정답

모범 답입니다.

<ul class="films">
  <li>우리들의 여름</li>
  <li>별을 찾는 아이</li>
  <li>마지막 상영</li>
  <li>바다로 가는 길</li>
</ul>
.films {
  padding: 0;
  list-style: none;
  /* 1. 목록에 grid */
  display: grid;
  /* 2. 열 최소 폭 */
  grid-template-columns:
    repeat(
      auto-fill,
      minmax(160px, 1fr)
    );
  /* 3. 간격 */
  gap: 12px;
}
결과 화면폭 600px
잰 값개발자 도구에서 본 값
  • .films의 열 수3
  • .films li의 너비186.66px

둘째 결과 — 창 폭 360에서 잰 것입니다.

<ul class="films">
  <li>우리들의 여름</li>
  <li>별을 찾는 아이</li>
  <li>마지막 상영</li>
  <li>바다로 가는 길</li>
</ul>
.films {
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns:
    repeat(
      auto-fill,
      minmax(160px, 1fr)
    );
  gap: 12px;
}
결과 화면폭 360px
잰 값개발자 도구에서 본 값
  • .films의 열 수2
  • .films li의 너비166px

확인한 결과가 둘 다 맞으면 맞습니다. 코드가 모범 답과 달라도 됩니다.

다르게 써도 되는 곳:

  • 세 하위 목표의 선언 차례는 바꿔도 됩니다.
  • auto-fill 대신 auto-fit도 이 목록에서는 같은 화면입니다. 카드 넷이 열 수보다 많아 빈 열이 생기지 않기 때문입니다 — 카드가 열 수보다 적으면 둘이 갈립니다.

흔한 잘못:

  • repeat(3, 1fr)로 열 수를 정하면 창 폭 600에서는 맞지만, 360에서도 세 열이라 카드가 106.66px로 좁아집니다. 열 수를 목록 폭에 맡기려면 auto-fill과 열 최소 폭을 씁니다.
  • repeat(auto-fill, 160px)⁠처럼 최솟값만 쓰면 열이 160px로 굳어, 남는 폭이 오른쪽에 빈 자리로 남습니다.
<ul class="films">
  <li>우리들의 여름</li>
  <li>별을 찾는 아이</li>
  <li>마지막 상영</li>
  <li>바다로 가는 길</li>
</ul>
.films {
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns:
    repeat(auto-fill, 160px);
  gap: 12px;
}
결과 화면폭 600px
잰 값개발자 도구에서 본 값
  • .films li의 너비160px
  • .films li:nth-child(3)의 오른쪽 끝512px

다시 볼 레슨: 들어가는 만큼 열 만들기

문제 13 (만들어 보기)

레시피 노트의 열두째 단계입니다(⟨컴퓨터⟩ · 20분 안팎 · 걸음마다 멈춰도 됩니다). 목록 페이지의 카드 여섯 장을 목록 폭에 맞춰 세 열 · 두 열 · 한 열로 바뀌는 격자로 놓습니다. 12단원 연습 문제의 만들어 보기를 마쳤다면 그 폴더에서 이어 갑니다.

이 단계 시작 파일 — 12단원 끝 상태

recipe-note 폴더에 세 파일을 받아 둡니다.

recipe-note 안에 images 폴더를 만들고 그림 여섯을 받아 둡니다. 앞 단계에서 받았으면 그대로 씁니다.

할 일 — 걸음 셋입니다. 이 단계는 style.css의 '레시피 목록' 구역만 고칩니다.

걸음 1 — 목록에 grid. .recipe-list 규칙에 display: grid를 더합니다.

걸음 2 — 열 최소 폭과 간격. 같은 규칙에 카드가 260px보다 좁아지지 않고 열 수는 목록 폭에 맡기는 열 선언을 더하고, 카드 사이를 16px 띄웁니다.

걸음 3 — 카드의 폭과 아래 여백 지우기. .recipe-card 규칙에서 max-width: 320px과 margin: 0 0 16px 두 줄을 지웁니다. 이제 카드의 폭은 격자 칸이, 카드 사이는 gap이 정합니다.

확인 목록:

  • 창 폭 1280에서 카드가 한 줄에 셋씩 두 줄이다(화면 · 걸음 2).
  • 창 폭을 천천히 줄이면 세 열 → 두 열 → 한 열로 바뀌고, 그 사이에는 카드가 넓어져 줄 끝까지 채운다(화면 · 걸음 2).
  • 마지막 줄 카드도 위 줄 카드와 폭이 같다(화면 · 걸음 2).
  • 카드 사이 가로 간격과 세로 간격이 같다 — Computed 창에서 .recipe-list의 row-gap · column-gap이 16px이다(화면 · Computed 창 · 걸음 2).
  • 카드가 격자 칸을 꽉 채운다 — 두 열이 되는 창 폭 800에서도 카드 오른쪽에 빈 자리가 없다(화면 · 걸음 3).
  • 창 폭을 줄일 수 있는 데까지 줄여도 가로 스크롤이 없다 — 열 수만 줄고 카드가 창 밖으로 나가지 않는다(화면 · 세 걸음 끝).

폰으로만 따라왔다면 이 물음 하나로 대신합니다. 걸음 1 · 2만 하고 걸음 3을 빠뜨린 채 창 폭 800에서 보면 카드는 어떻게 보일까요?

  • ① 카드가 칸을 꽉 채운다
  • ② 카드가 칸보다 좁아 칸 오른쪽에 빈 자리가 남는다
  • ③ 카드가 칸보다 넓어 옆 카드와 겹친다
힌트

걸음마다 그 걸음의 확인 목록을 봅니다. 걸음 2의 열 선언은 카드 격자 틀의 하위 목표 2 그대로입니다.

정답

모범 답입니다. 바뀐 곳은 '레시피 목록' 구역의 두 규칙뿐입니다 — 다 고친 style.css는 아래 받기 파일과 같습니다(index.html · kimchi.html은 12단원 끝 상태 그대로).

/* 레시피 목록 */
.recipe-list {
  display: grid;
  grid-template-columns:
    repeat(
      auto-fill,
      minmax(260px, 1fr)
    );
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style-type: none;
}
.recipe-card {
  padding: 16px;
  border:
    1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  …
}

목록을 떼어 창 폭 1280에서 그린 모습입니다. 리셋 · 본문 · 목록 규칙은 받기 파일과 같은 선언만 골랐습니다.

<main>
  <ul class="recipe-list">
    <li>김치볶음밥</li>
    <li>계란말이</li>
    <li>된장찌개</li>
    <li>떡볶이</li>
    <li>잡채</li>
    <li>미역국</li>
  </ul>
</main>
* {
  box-sizing: border-box;
}

main {
  max-width: 960px;
  margin: 0 auto;
  padding: 24px 16px;
}
결과 화면폭 1280px
.recipe-list {
  display: grid;
  grid-template-columns:
    repeat(
      auto-fill,
      minmax(260px, 1fr)
    );
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style-type: none;
}
결과 화면폭 1280px
잰 값개발자 도구에서 본 값
  • .recipe-list의 너비928px
  • .recipe-list의 열 수3
  • .recipe-list의 줄 수2
  • .recipe-list li의 너비298.66px

첫 결과 화면은 앞 CSS만, 둘째 결과 화면은 이어 쓴 CSS까지 그린 것입니다. main은 리셋으로 안쪽 여백까지 960px 안에 들어, 목록 폭이 928px입니다.

확인 목록을 다 채웠으면 맞습니다. 코드가 모범 답과 달라도 됩니다.

다르게 써도 되는 곳:

  • .recipe-list 안 선언의 차례는 바꿔도 됩니다.
  • gap: 16px 대신 row-gap · column-gap을 따로 16px씩 적어도 같습니다.

흔한 잘못:

  • 걸음 3을 빠뜨리면 두 열이 되는 폭(창 800에서 칸 376px)에서 카드가 320px에 멈춰 칸 오른쪽에 빈 자리가 남습니다. 카드 아래 여백 16px도 남아, 줄 사이가 gap과 합쳐 32px로 벌어집니다 — flex 안에서처럼 격자 안에서도 바깥 여백은 겹치지 않습니다.
  • 열을 repeat(3, 1fr)로 정하면 창 1280에서는 맞지만, 창 360에서도 세 열이라 카드가 좁게 눌립니다. 확인 목록의 '한 열로 바뀐다'로 찾습니다.
  • 격자를 .recipe-card에 주면 카드 하나하나가 격자가 되고, 카드끼리는 그대로 위아래로 쌓입니다. 격자는 카드를 담은 목록 .recipe-list에 줍니다.

폰 물음의 답은 ②입니다. 창 폭 800에서 목록은 안쪽 여백을 뺀 768px이라 두 열이고, 칸은 (768 − 16) ÷ 2 = 376px인데 카드는 max-width: 320px에서 멈춥니다. 세 열이 되는 창 폭 844부터는 칸이 320px보다 좁아 빈 자리가 보이지 않습니다.

다시 볼 레슨: flex 여러 줄과 grid · 들어가는 만큼 열 만들기

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

HTML·CSS 목차로