본문으로 건너뛰기

단원 연습 문제

HTML·CSS 목차화면 폭에 맞추기문제 13개

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

결과를 묻는 문제의 결과 화면과 잰 값은 정답을 펼치면 보입니다. 폭이 중요한 문제는 문제에 적은 화면 폭으로 그렸습니다. 1번은 휴대전화에서만 생기는 일이라 결과 화면으로 그리지 못해, 크롬 기기 흉내로 잰 값을 정답에 적었습니다. 컴퓨터가 있으면 문제의 HTML과 CSS를 파일로 저장해 열고, 개발자 도구 기기 모드로 폭을 바꿔 가며 Computed 창에서 값을 맞춰 봅니다. 결과는 모두 크롬 기준입니다.

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

문제 1

동아리 공지 페이지의 head에 뷰포트 줄을 빠뜨렸습니다. 화면 폭이 412px인 휴대전화로 이 페이지를 엽니다.

<head>
  <meta charset="utf-8" />
  <title>동아리 공지</title>
</head>
…

(가) 이 휴대전화가 페이지를 배치하는 폭(창의 너비)은 몇 px일까요? 보기에서 고르세요.

  • ① 412
  • ② 980
  • ③ 1280

(나) 뷰포트 줄 content="width=device-width"⁠를 넣은 뒤, 같은 휴대전화에서 h1의 너비는 몇 px일까요? body의 바깥 여백은 처음 값 8px입니다. 숫자만 쓰세요.

힌트

(가)는 보기 셋의 숫자가 저마다 어디서 나온 폭인지 적어 보세요.

힌트 둘

head에 있는 줄과 빠진 줄을 적고, 빠진 줄이 정하는 값이 무엇이었는지 떠올려 보세요.

정답

(가) ② · (나) 396

  • (가) 휴대전화 브라우저는 뷰포트 줄이 없는 페이지를 넓은 화면처럼 980px 폭으로 배치하고, 그 980px을 화면 폭에 맞게 통째로 줄여 보입니다 — 412 ÷ 980이라 약 0.42배로 작게 보입니다.
  • (나) 뷰포트 줄이 있으면 기기 화면 폭 412px로 배치합니다. h1은 블록이라 부모 내용 칸을 채워 412 − 8 × 2 = 396px입니다(브라우저 규칙 6).

결과 화면은 컴퓨터 브라우저 안의 틀이라 뷰포트 줄을 따르지 않습니다. (가)는 크롬 기기 흉내(화면 폭 412px 휴대전화)로 잰 값입니다 — 줄이 없으면 창의 너비 980px · h1 964px · 0.42배, 줄이 있으면 412px · 396px. 아래 결과 화면은 줄이 있을 때의 모양입니다.

<h1>동아리 공지</h1>
결과 화면폭 412px
잰 값개발자 도구에서 본 값
  • 창의 너비412px
  • h1의 너비396px
  • (가) ①은 휴대전화가 뷰포트 줄 없이도 화면 폭에 알아서 맞춘다고 본 것입니다(휴대전화가 알아서 맞춘다는 생각).
  • (가) ③은 컴퓨터 창의 폭이 휴대전화에도 쓰인다고 본 것입니다. 980은 휴대전화 브라우저가 정해 둔 폭입니다.

다시 볼 레슨: meta viewport

문제 2

.g를 넓은 화면에서만 격자로 바꾸는 조건 블록입니다. (가) 화면 폭 640px에서 결과 화면은 어떻게 보일까요? 보기 셋 가운데 고르세요. (나) 화면 폭 639px에서는 보기 가운데 어느 것과 같을까요?

<div class="g">
  <mark>가</mark><mark>나</mark>
</div>
@media (min-width: 640px) {
  .g {
    display: grid;
  }
}
힌트

640px과 639px 각각에서 조건 min-width: 640px이 맞는지 먼저 적고, 맞을 때 .g에 드는 선언을 적어 보세요.

힌트 둘

min-width: 640px은 '폭이 640px 이상'입니다. 열을 정하지 않은 격자가 몇 열인지도 떠올리세요.

정답

(가) ③ — 노란 띠 둘이 위아래로 쌓입니다 · (나) ①

결과 화면폭 640px
  • (가) min-width: 640px은 폭이 640px 이상일 때 맞아, 640px에서 조건 블록이 듭니다(브라우저 규칙 4). .g는 격자가 되고, 열을 정하지 않아 한 열입니다. 두 mark는 격자 항목이 되어 넓은 띠로 한 줄씩 놓입니다.

  • (나) 639px에서는 조건이 맞지 않아 조건 블록이 들지 않습니다. .g는 보통 블록이고 mark는 글자만큼 칠한 채 한 줄에 놓입니다 — CSS가 없는 ①과 같은 화면입니다.

  • (가)에서 ①을 골랐다면 min-width: 640px이 640을 빼고 641부터라고 본 것입니다(경계를 빼는 생각).

  • (가)에서 ②를 골랐다면 격자가 되면 저절로 두 열이 된다고 본 것입니다. 열을 정하지 않은 격자는 한 열입니다.

다시 볼 레슨: 모바일 먼저와 미디어 쿼리 · flex 여러 줄과 grid

문제 3

레시피 노트 머리글을 넓은 화면에서만 굴려도 창 맨 위에 붙게 했습니다. 페이지를 300px 내린 뒤 머리글 .top의 창 위 자리는 몇 px일까요? (가) 화면 폭 639px (나) 화면 폭 640px. 숫자만 쓰세요(위로 벗어나면 음수).

<header class="top">
  레시피 노트
</header>
<div class="long">본문</div>
body {
  margin: 0;
}

.long {
  height: 1600px;
}

@media (min-width: 640px) {
  .top {
    position: sticky;
    top: 0;
  }
}
힌트

폭마다 조건 블록이 드는지 먼저 정해 보세요.

힌트 둘

조건 블록이 들지 않는 폭에서는 머리글의 position이 무엇인지 적어 보세요.

정답

(가) −300 · (나) 0

결과 화면폭 639px
잰 값개발자 도구에서 본 값
  • .top의 positionstatic
  • .top의 창 위 자리-300px

(나) 같은 코드를 640px에서 300px 내린 뒤입니다.

<header class="top">
  레시피 노트
</header>
<div class="long">본문</div>
body {
  margin: 0;
}

.long {
  height: 1600px;
}

@media (min-width: 640px) {
  .top {
    position: sticky;
    top: 0;
  }
}
결과 화면폭 640px
잰 값개발자 도구에서 본 값
  • .top의 positionsticky
  • .top의 창 위 자리0px
  • (가) 639px에서는 조건 블록이 들지 않아 머리글은 처음 값 static입니다. 페이지와 함께 300px 올라가 창 위에서 −300px입니다.
  • (나) 640px부터 조건 블록이 들어 position: sticky · top: 0이 닿습니다. 원래 자리가 창 위를 지나 올라가면 거기에 붙어 0px입니다(브라우저 규칙 8).
  • (가)에서 흔한 오답은 0입니다. 조건 블록 안에 적은 선언도 늘 든다고 본 것입니다.

다시 볼 레슨: sticky 머리글과 z-index · 모바일 먼저와 미디어 쿼리

문제 4

플로우 카페 사진 칸을 넓은 화면에서 세 열로 바꾸려고 조건 블록을 맨 위에 썼습니다. 화면 폭 900px에서 (가) 사진 칸은 몇 열일까요? (나) 조건 블록 안의 선택자만 main .shots로 바꾸면 몇 열일까요? 숫자만 쓰세요.

<main>
  <div class="shots">
    <div>아인슈페너</div>
    <div>크루아상</div>
    <div>휘낭시에</div>
  </div>
</main>
@media (min-width: 640px) {
  .shots {
    grid-template-columns:
      repeat(3, 1fr);
  }
}

.shots {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
힌트

900px에서 조건 블록이 드는지 정한 뒤, grid-template-columns 선언 둘을 손 점수판에 적어 보세요.

힌트 둘

조건 블록은 조건이 맞을 때 안의 규칙을 들일 뿐, 명시도나 차례를 바꾸지 않습니다.

정답

(가) 1 · (나) 3

결과 화면폭 900px
잰 값개발자 도구에서 본 값
  • .shots의 열 수1
속성선언출처명시도차례이긴 값
grid-template-columns.shots · 1fr우리 CSS0-1-021fr
조건 블록 .shots · repeat(3, 1fr)우리 CSS0-1-01

차례 칸은 규칙 차례(조건 블록 안 .shots 1 · 아래 .shots 2)이고, 줄은 명시도의 점수판처럼 이긴 선언부터 적었습니다 — 코드 차례로 적어도 칸의 값이 같으면 맞습니다.

  • (가) 900px에서 조건이 맞아 조건 블록 안 규칙도 듭니다. 그래도 두 선언은 명시도가 같고, 나중에 쓴 기본 규칙의 1fr이 이깁니다(브라우저 규칙 5). 조건 블록은 기본 규칙 아래에 둡니다.
  • (나) 선택자를 main .shots(0-1-1)로 바꾸면 명시도에서 .shots(0-1-0)를 이겨, 위에 있어도 세 열입니다.
<main>
  <div class="shots">
    <div>아인슈페너</div>
    <div>크루아상</div>
    <div>휘낭시에</div>
  </div>
</main>
@media (min-width: 640px) {
  main .shots {
    grid-template-columns:
      repeat(3, 1fr);
  }
}

.shots {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
결과 화면폭 900px
잰 값개발자 도구에서 본 값
  • .shots의 열 수3
  • (가)에서 흔한 오답은 3입니다. 조건이 맞으면 조건 블록 안 선언이 늘 이긴다고 본 것입니다. 조건 블록 안이라고 명시도가 오르지 않습니다.
  • (나)에서 1은 차례만 본 것입니다. 명시도가 다르면 차례보다 명시도를 먼저 봅니다.

다시 볼 레슨: 모바일 먼저와 미디어 쿼리 · 명시도

문제 5

짝마다 두 코드의 화면이 같은지 다른지 쓰세요. (가) · (나)는 화면 폭 800px에서 견줍니다. 다르면 어디가 다른지도 한 줄로 쓰세요. 셋 모두 같은 답이 나와도 됩니다.

(가)

<p class="a">휴무 안내</p>
@media (min-width: 640px) {
  .a {
    color: #d70015;
  }
}
<p class="a">휴무 안내</p>
@media (min-width: 640) {
  .a {
    color: #d70015;
  }
}

(나)

<p class="a">휴무 안내</p>
.a {
  color: #005bb5;
}

@media (min-width: 640px) {
  .a {
    color: #d70015;
  }
}
<p class="a">휴무 안내</p>
.a {
  color: #d70015;
}

@media (max-width: 639px) {
  .a {
    color: #005bb5;
  }
}

(다)

<img
  src="images/wide.webp"
  width="400"
  height="300"
  alt="김치볶음밥"
/>
img {
  width: 120px;
  height: auto;
  aspect-ratio: 3 / 4;
}
<img
  src="images/wide.webp"
  width="400"
  height="300"
  alt="김치볶음밥"
/>
img {
  width: 120px;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: fill;
}
힌트

짝마다 바뀐 줄을 찾고, 그 줄이 800px에서 무슨 일을 하는지 적어 보세요.

힌트 둘

(가)는 조건의 글자를 한 자씩 견주고, (다)는 object-fit을 적지 않았을 때의 값을 떠올려 보세요.

정답

(가) 다르다 — 앞 코드는 글자가 빨강, 뒤 코드는 검정 · (나) 같다 · (다) 같다

결과 화면(가) 첫째 코드
결과 화면(가) 둘째 코드
결과 화면(나) 첫째 코드
결과 화면(나) 둘째 코드
결과 화면(다) 첫째 코드
결과 화면(다) 둘째 코드
  • (가) 조건의 640에 단위가 없어, 뒤 코드의 조건은 어느 폭에서도 맞지 않습니다. 조건 블록이 들지 않아 글자는 처음 색 검정입니다.
  • (나) 앞 코드는 좁은 화면 파랑을 기본으로 두고 640px부터 빨강, 뒤 코드는 넓은 화면 빨강을 기본으로 두고 639px까지 파랑입니다. 800px에서는 둘 다 빨강입니다 — 쓰는 차례가 거꾸로일 뿐, 이 폭에서 이긴 값이 같습니다.
  • (다) object-fit의 처음 값이 fill이라, 적지 않은 것과 fill을 적은 것은 같습니다. 둘 다 가로로 긴 사진을 세로로 긴 3:4 칸(120 × 160)에 맞춰 옆으로 눌러 찌그러뜨립니다 — 둥근 그릇이 세로로 긴 타원이 됩니다.
  • (가) 같다는 브라우저가 빠진 px을 채워 읽는다고 본 것입니다. CSS는 알아듣지 못한 조건을 맞지 않는 것으로 칩니다.
  • (나) 다르다는 min-width와 max-width가 늘 다른 화면을 낸다고 본 것입니다.
  • (다) 다르다는 fill이 칸을 채우되 비율은 지킨다고 본 것입니다. 비율을 지키며 채우는 값은 cover입니다.

다시 볼 레슨: 모바일 먼저와 미디어 쿼리 · 그림을 칸에 맞추기: aspect-ratio·object-fit

문제 6

여행 일정 페이지 '시장 먹거리' 칸에 세로로 긴 사진(원본 300 × 400)을 넣고, 칸보다 넓어지지 않게 max-width만 줬습니다. (가) 사진의 너비와 높이는 몇 px일까요? (나) 사진이 찌그러지지 않게 img 규칙에 선언 한 줄을 더하면 높이는 몇 px이 될까요? 더할 줄과 높이를 쓰세요.

<div class="food">
  <img
    src="images/tall.webp"
    width="300"
    height="400"
    alt="떡볶이"
  />
</div>
.food {
  width: 150px;
}

img {
  max-width: 100%;
}
힌트

img에 닿는 CSS 선언과 HTML 속성을 너비 · 높이 두 칸으로 나눠 적어 보세요.

힌트 둘

max-width는 너비의 상한만 정합니다. 높이를 정한 곳이 따로 있는지 보세요.

정답

(가) 150 · 400 · (나) height: auto; · 200

결과 화면
잰 값개발자 도구에서 본 값
  • img의 너비150px
  • img의 높이400px
  • (가) max-width: 100%는 너비만 칸의 내용 칸 150px로 줄입니다. 높이는 HTML의 height="400" 그대로라, 300 × 400 사진이 150 × 400 칸에 맞춰 가로로 눌려 찌그러집니다(브라우저 규칙 6).
  • (나) height: auto를 더하면 높이를 원본 비율대로 셈합니다 — 150 × 400 ÷ 300 = 200px입니다.
img {
  height: auto;
}
결과 화면
잰 값개발자 도구에서 본 값
  • img의 너비150px
  • img의 높이200px

첫 결과 화면은 찌그러진 앞 코드, 둘째 결과 화면은 한 줄을 더한 뒤입니다.

  • (가)에서 흔한 오답은 150 · 200입니다. max-width가 너비를 줄이면 높이도 비율대로 따라 준다고 본 것입니다.

다시 볼 레슨: 유연한 그림

문제 7

레시피 노트 '오늘의 반찬' 칸에 안쪽 여백과 테두리를 주고, 안의 그림을 max-width: 100%로 맞췄습니다. (가) 그림의 너비는 몇 px일까요? (나) 칸 .dish가 차지하는 너비는 몇 px일까요? 숫자만 쓰세요.

<div class="dish">
  <img
    src="images/japchae.svg"
    width="800"
    height="600"
    alt="잡채"
  />
</div>
.dish {
  width: 220px;
  padding: 12px;
  border: 3px solid #6e6e73;
}

img {
  max-width: 100%;
  height: auto;
}
힌트

.dish의 상자 셈 표를 채우고, max-width: 100%의 100%가 그 가운데 어느 칸인지 정해 보세요.

정답

(가) 220 · (나) 250

결과 화면
잰 값개발자 도구에서 본 값
  • img의 너비220px
  • .dish의 width220px
  • .dish의 너비250px
걸음셈값
1. 내용 칸width220
2. 안쪽 여백 더하기220 + 12 × 2244
3. 테두리 더하기244 + 3 × 2250
4. 바깥 여백은 따로없음—
  • %는 부모의 내용 칸을 기준으로 합니다. width: 220px이 내용 칸이니 그림은 220px까지 줄고, 칸이 차지하는 너비는 안쪽 여백과 테두리를 더한 250px입니다(브라우저 규칙 6).
  • 흔한 오답은 (가) 190 · (나) 220입니다. width가 칸이 차지하는 너비라고 보고, 220에서 안쪽 여백과 테두리를 뺀 것입니다(width가 차지하는 너비라는 생각).

다시 볼 레슨: 너비와 box-sizing · 유연한 그림

문제 8

플로우 카페 사이트에 events 폴더를 만들고 '가을 한 그릇 주간' 페이지를 그 안에 두었습니다. 첫 페이지에서 보이던 김치볶음밥 그림이 이 페이지에서는 깨져 보입니다. 이 페이지의 그림 줄은 첫 페이지 줄을 그대로 복사했습니다.

flow-cafe/
  index.html
  images/
    kimchi.svg
  events/
    autumn.html
<img
  src="images/kimchi.svg"
  …
/>

(가) events/autumn.html에서 브라우저가 이 그림을 받으러 가는 파일은 어느 것일까요?

  • ① flow-cafe/images/kimchi.svg
  • ② flow-cafe/events/images/kimchi.svg
  • ③ flow-cafe/events/kimchi.svg

(나) 이 페이지에서 그림이 보이도록 src 값을 고쳐 쓰세요.

힌트

상대 주소의 출발점을 폴더 나무에 표시하고, 그 폴더에서 images/kimchi.svg를 한 칸씩 따라가 보세요.

정답

(가) ② · (나) ../images/kimchi.svg

<img
  src="../images/kimchi.svg"
  …
/>
  • (가) 상대 주소는 그 주소를 적은 파일이 있는 폴더에서 출발합니다(브라우저 규칙 1). 이 페이지는 events 폴더에 있어 events/images/kimchi.svg⁠를 찾고, 그런 파일은 없어 그림이 깨집니다.
  • (나) ../로 한 폴더 올라가 flow-cafe/images/kimchi.svg⁠에 닿습니다.
  • (가)에서 ①을 골랐다면 상대 주소가 늘 사이트 폴더에서 출발한다고 본 것입니다(출발점이 늘 같다는 생각).
  • (나)를 /images/kimchi.svg로 썼다면 /가 사이트 폴더의 맨 위라고 본 것입니다. 내 컴퓨터에서 파일로 열면 /는 디스크의 맨 위라 그림이 깨집니다.
  • max-width · height: auto는 그림이 받아진 뒤의 크기만 정합니다. 깨진 그림은 CSS로 고쳐지지 않습니다.
  • 이 문제의 결과는 정답 칸에 그리지 않습니다. 결과 화면은 페이지를 events 같은 폴더 안에 두지 못해 ../가 실제 폴더와 다르게 풀립니다. 컴퓨터에서 폴더를 만들어 확인해 보세요.

다시 볼 레슨: 경로 읽기 · 그림 넣기 img

문제 9

동아리 공지 페이지의 두 칸 줄이 화면 폭 360px에서 가로 스크롤을 만듭니다. (가) 페이지의 너비는 몇 px일까요? 숫자만 쓰세요. (나) 열 값 50% 50%를 무엇으로 바꾸면 가로 스크롤이 없어질까요?

<div class="two">
  <p>여름 캠프</p>
  <p>가을 축제</p>
</div>
.two {
  display: grid;
  grid-template-columns:
    50% 50%;
  gap: 24px;
}
힌트

.two의 너비를 먼저 셈하고, 그 줄 안에 든 것의 폭을 모두 더해 보세요.

힌트 둘

% 열은 간격을 빼지 않고 부모 너비의 그 몫을 그대로 가집니다. 간격은 그 위에 더 붙습니다.

정답

(가) 376 · (나) 1fr 1fr

결과 화면일부러 틀린 코드
잰 값개발자 도구에서 본 값
  • .two의 너비344px
  • 페이지의 너비376px
  • 창의 너비360px
  • .two는 360 − 8 × 2 = 344px이고, 50% 두 열이 172px씩 344px을 다 쓴 뒤 간격 24px이 더 붙습니다. 344 + 24 = 368px이 왼쪽 여백 8px에서 시작해 376px까지 나갑니다.
  • fr은 간격을 먼저 빼고 남는 폭을 나눠, 두 열이 160px씩 344px 안에 듭니다.
.two {
  grid-template-columns:
    1fr 1fr;
}
결과 화면폭 360px
잰 값개발자 도구에서 본 값
  • 페이지의 너비360px
  • .two p의 너비160px

찾는 차례 다섯째 줄대로, 기기 모드 360에서 처음으로 창 끝을 넘는 상자가 .two의 둘째 칸입니다.

  • 흔한 오답은 (가) 360입니다. 50% 둘이면 딱 맞는다고 보고 간격을 셈에 넣지 않은 것입니다.
  • body { overflow-x: hidden; }⁠으로 가로 스크롤을 감추면 둘째 칸 오른쪽이 잘려 안 보입니다 — 넘친 것은 그대로입니다.

다시 볼 레슨: 가로 스크롤 원인 찾기 · 열 만들기

문제 10

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

  • (가) 조건이 맞을 때만 안의 규칙을 들이는 CSS 블록의 머리 낱말
  • (나) 칸의 가로세로 비율을 정하는 CSS 속성
  • (다) 사진을 찌그러뜨리지 않고 칸을 꽉 채우며, 칸 밖으로 남는 곳은 잘라 내는 object-fit 값
  • (라) 빈칸 없는 긴 영문 낱말을 칸 끝에서 꺾어 다음 줄로 넘기는 선언
힌트

(가)는 모바일 먼저 틀의 하위 목표 2에 쓴 블록, (나) · (다)는 카드 사진 칸 레슨, (라)는 가로 스크롤 원인 표의 '긴 영문 덩어리' 줄입니다.

정답

받는 답: (가) @media · (나) aspect-ratio · (다) cover · (라) overflow-wrap: anywhere

  • 같은 답으로 치는 꼴: (가) @media (min-width: 640px)⁠처럼 조건까지 써도 됩니다. (라) overflow-wrap: break-word⁠도 보통 블록 안에서는 같은 화면입니다 — 다만 flex 항목 안에서는 긴 낱말을 꺾지 못하고 넘쳐, 레슨은 anywhere를 씁니다.
  • 틀리는 꼴 — (다) contain은 사진을 다 보이되 빈 띠를 남기고, fill은 칸을 채우되 찌그러뜨립니다. (라) word-break: break-all⁠도 꺾지만, 영문 낱말을 아무 데서나 끊어 읽기 어렵습니다. overflow-x: hidden은 넘친 것을 감출 뿐 꺾지 않습니다.

다시 볼 레슨: 모바일 먼저와 미디어 쿼리 · 그림을 칸에 맞추기: aspect-ratio·object-fit · 가로 스크롤 원인 찾기

문제 11

여행 일정 페이지 '첫날 저녁' 칸을 기기 모드 360px로 보니 가로 스크롤이 생기고, 그림 오른쪽이 창 밖으로 나갑니다. 튀어나온 상자를 찾아 그림을 고르니 Computed 창의 너비가 800px입니다. img 규칙에 무엇을 더해야 할까요? 더할 줄을 쓰세요.

<div class="day">
  <h2>첫날 저녁</h2>
  <img
    src="images/doenjang.svg"
    width="800"
    height="600"
    alt="된장찌개"
  />
</div>
.day {
  padding: 12px;
  border: 1px solid #d2d2d7;
}

img {
  display: block;
  height: auto;
}
결과 화면일부러 틀린 코드
힌트

찾는 차례대로 1번부터 지워 가세요. 5번에서는 처음으로 창 끝을 넘는 상자를 찾고, 그 상자의 너비가 어디에서 왔는지 봅니다.

힌트 둘

그림은 HTML의 width="800"대로 그려집니다. 부모보다 넓어지지 않게 너비 상한을 주는 선언을 떠올리세요.

정답

받는 답: img 규칙에 max-width: 100%;를 더합니다.

<div class="day">
  <h2>첫날 저녁</h2>
  <img
    src="images/doenjang.svg"
    width="800"
    height="600"
    alt="된장찌개"
  />
</div>
.day {
  padding: 12px;
  border: 1px solid #d2d2d7;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}
결과 화면폭 360px
잰 값개발자 도구에서 본 값
  • 페이지의 너비360px
  • img의 너비318px
  • img의 높이238.5px

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

  • 1번 ~ 4번 — 그림이 그려지니 파일도 그림 주소도 닿았고, Styles 창에 img 규칙이 보이며 선언에 취소선도 경고 표시도 없습니다.
  • 5번 — 기기 모드 360에서 오른쪽으로 튀어나온 곳을 검사하면, 처음으로 창 끝을 넘는 상자가 그림입니다. Computed 창의 너비 800px은 HTML의 width="800"에서 왔습니다.

max-width: 100%는 그림이 부모의 내용 칸(360 − 8 × 2 − 1 × 2 − 12 × 2 = 318px)보다 넓어지지 않게 합니다. height: auto가 이미 있어 높이도 318 × 600 ÷ 800 = 238.5px로 비율대로 줍니다(브라우저 규칙 6).

다르게 고쳐도 되는 곳: width: 100%도 이 그림에서는 같은 화면입니다. 다만 칸보다 작은 그림까지 칸 폭으로 키워 흐려지니, 그림에는 max-width를 씁니다.

  • 흔한 오답은 body { overflow-x: hidden; }⁠입니다. 가로 스크롤은 사라져도 그림 오른쪽이 잘린 채입니다.
  • HTML의 width="800" · height="600"을 지우는 것도 흔합니다. 불러오는 동안 자리를 잡지 못해 글이 밀리니 HTML 속성은 그대로 둡니다.

다시 볼 레슨: 유연한 그림 · 가로 스크롤 원인 찾기

문제 12 (만들어 보기)

플로우 카페 문 여는 시간 줄입니다. 좁은 화면에서는 요일 아래에 시간이 오고, 화면 폭 600px부터는 요일과 시간이 한 줄 양 끝에 놓이게 하려 합니다. 하위 목표 주석만 남긴 틀의 …를 채우세요.

<div class="hours">
  <p>월 ~ 금</p>
  <p>오전 8시 ~ 오후 9시</p>
</div>
/* 1. 좁은 화면 기본 규칙 */
.hours {
  …
}
/* 2. 넓어지면 바뀔 선언만 */
…

나와야 할 결과는 둘입니다 — 하위 목표 3 '경계 폭에서 확인'입니다.

  • 화면 폭 599px에서 요일과 시간이 위아래 두 줄이다.
  • 화면 폭 600px에서 요일과 시간이 한 줄 양 끝에 놓인다.
힌트

하위 목표 1에는 좁은 화면의 배치를 다 쓰고, 2의 조건 블록에는 넓어질 때 바뀌는 선언만 넣습니다.

정답

모범 답입니다.

<div class="hours">
  <p>월 ~ 금</p>
  <p>오전 8시 ~ 오후 9시</p>
</div>
/* 1. 좁은 화면 기본 규칙 */
.hours {
  display: flex;
  flex-direction: column;
}
/* 2. 넓어지면 바뀔 선언만 */
@media (min-width: 600px) {
  .hours {
    flex-direction: row;
    justify-content:
      space-between;
  }
}
결과 화면폭 599px
잰 값개발자 도구에서 본 값
  • .hours의 줄 수2

둘째 결과 — 화면 폭 600px에서 잰 것입니다.

<div class="hours">
  <p>월 ~ 금</p>
  <p>오전 8시 ~ 오후 9시</p>
</div>
.hours {
  display: flex;
  flex-direction: column;
}
@media (min-width: 600px) {
  .hours {
    flex-direction: row;
    justify-content:
      space-between;
  }
}
결과 화면폭 600px
잰 값개발자 도구에서 본 값
  • .hours의 줄 수1
  • .hours p:last-child의 오른쪽 끝592px

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

다르게 써도 되는 곳:

  • 하위 목표 1을 비워 두고(보통 블록이라 위아래로 쌓임), 조건 블록에 display: flex와 justify-content: space-between⁠을 넣어도 두 결과를 다 채웁니다(599px에서는 일반 흐름이라 두 줄 사이의 바깥 여백이 겹쳐 조금 좁습니다).

흔한 잘못:

  • 조건을 (max-width: 600px)로 쓰면 거꾸로 600px 이하에서 드는 블록이 되어, 599px · 600px 둘 다 같은 배치가 됩니다.
  • 조건에 단위를 빠뜨린 (min-width: 600)은 어느 폭에서도 맞지 않아, 600px에서도 위아래 두 줄입니다.
  • 조건 블록을 하위 목표 1보다 위에 쓰면 뒤에 쓴 기본 규칙의 flex-direction: column⁠이 이겨, 넓은 화면에서도 두 줄입니다.

다시 볼 레슨: 모바일 먼저와 미디어 쿼리

문제 13 (만들어 보기)

레시피 노트의 열넷째 단계입니다(⟨컴퓨터⟩ · 25분 안팎 · 걸음마다 멈춰도 됩니다). 두 페이지가 화면 폭 320px부터 1280px까지 가로 스크롤 없이 보이게 하고, 머리글을 좁은 화면에서는 위아래로, 넓은 화면에서는 한 줄로 놓습니다. 14단원 연습 문제의 만들어 보기를 마쳤다면 그 폴더에서 이어 갑니다.

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

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

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

할 일 — 걸음 넷입니다. 이 단계는 style.css만 고칩니다. 두 페이지의 뷰포트 줄은 1단원부터 이미 있습니다.

걸음 1 — 그림이 칸보다 넓어지지 않게. '기본' 구역에 모든 img의 너비 상한을 부모 폭으로 두고, 높이는 비율대로 따라오게 하는 규칙을 더합니다.

걸음 2 — 긴 낱말 꺾기. main 규칙에 빈칸 없는 긴 낱말을 칸 끝에서 꺾는 선언을 더합니다.

걸음 3 — 머리글 모바일 먼저. .site-header 기본 규칙은 좁은 화면 배치로 바꿉니다 — 위아래로 쌓고(flex-direction: column), 왼쪽 끝에 맞추고(align-items: flex-start), 사이를 12px 띄웁니다. 파일 맨 끝에 /* 화면 폭 */ 구역을 두고, 화면 폭 640px부터 한 줄 · 세로 가운데로 바뀔 선언만 조건 블록에 넣습니다.

걸음 4 — 자리가 모자라면 다음 줄로. 내비게이션 nav와 후기 폼 줄 .form-row에 flex-wrap: wrap을 더합니다.

확인 목록:

  • 개발자 도구 기기 모드로 320 · 639 · 640 · 1280에서 두 페이지 모두 가로 스크롤이 없다 — 페이지를 옆으로 밀어도 움직이지 않는다(기기 모드 · 네 걸음 끝).
  • 320에서 카드 그림이 카드 안에 들어온다(화면 · 걸음 1).
  • 639에서 머리글의 사이트 이름 아래에 내비게이션이 오고, 640에서 한 줄 양 끝에 놓인다(화면 · Computed 창 flex-direction · 걸음 3).
  • nav와 .form-row의 Computed 창 flex-wrap이 wrap이다. 지금 두 페이지는 320에서도 한 줄에 다 들어 화면으로는 가를 수 없고, 한 줄에 들지 않을 때 다음 줄로 넘어간다(Computed 창 · 걸음 4).
  • 1280에서는 14단원 끝과 모양이 같다 — 카드 세 열 · 머리글 한 줄(화면 · 네 걸음 끝).

폰으로만 따라왔다면 이 물음 하나로 대신합니다. 걸음 3을 마친 머리글은 화면 폭 639px과 640px에서 각각 어떻게 놓일까요?

  • ① 639px 위아래 · 640px 한 줄
  • ② 둘 다 위아래
  • ③ 639px 한 줄 · 640px 위아래
힌트

걸음마다 그 걸음의 확인 목록을 봅니다. 걸음 3은 모바일 먼저 틀 그대로 — 1. 좁은 화면 기본 규칙 → 2. 넓어지면 바뀔 선언만 → 3. 경계 폭(639 · 640)에서 확인입니다.

정답

모범 답입니다. 바뀐 곳만 싣습니다 — 다 고친 style.css는 아래 받기 파일과 같습니다(index.html · kimchi.html은 14단원 끝 상태 그대로).

img {
  max-width: 100%;
  height: auto;
}

main {
  …
  overflow-wrap: anywhere;
}
.site-header {
  …
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  …
}

nav {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
/* 화면 폭 */
@media (min-width: 640px) {
  .site-header {
    flex-direction: row;
    align-items: center;
  }
}

.form-row 규칙에도 flex-wrap: wrap; 한 줄을 더합니다.

머리글만 떼어 경계 폭 둘에서 그린 모습입니다. 받기 파일과 같은 선언만 골랐습니다.

<header class="site-header">
  <a href="index.html">
    레시피 노트
  </a>
  <nav>
    <a href="kimchi.html">
      김치볶음밥
    </a>
  </nav>
</header>
.site-header {
  display: flex;
  flex-direction: column;
  justify-content:
    space-between;
  align-items: flex-start;
  gap: 12px;
}
@media (min-width: 640px) {
  .site-header {
    flex-direction: row;
    align-items: center;
  }
}
결과 화면폭 639px
잰 값개발자 도구에서 본 값
  • .site-header의 flex-directioncolumn
  • .site-header의 줄 수2
<header class="site-header">
  <a href="index.html">
    레시피 노트
  </a>
  <nav>
    <a href="kimchi.html">
      김치볶음밥
    </a>
  </nav>
</header>
.site-header {
  display: flex;
  flex-direction: column;
  justify-content:
    space-between;
  align-items: flex-start;
  gap: 12px;
}
@media (min-width: 640px) {
  .site-header {
    flex-direction: row;
    align-items: center;
  }
}
결과 화면폭 640px
잰 값개발자 도구에서 본 값
  • .site-header의 flex-directionrow
  • .site-header의 줄 수1

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

다르게 써도 되는 곳:

  • 걸음 1의 규칙을 .recipe-card img처럼 카드 그림에만 써도 이 두 페이지에서는 넘침이 없습니다. 다만 뒤에 넓은 그림을 더할 때마다 같은 규칙이 필요하니 모든 img에 둡니다.
  • 걸음 3의 조건 블록을 파일 끝이 아니라 .site-header 규칙 바로 아래에 둬도 됩니다. 기본 규칙보다 아래이기만 하면 됩니다.

흔한 잘못:

  • 조건 블록을 .site-header 기본 규칙보다 위에 두면, 640px 이상에서도 뒤의 flex-direction: column⁠이 이겨 머리글이 늘 위아래입니다.
  • 걸음 3에서 조건 블록에 display: flex · gap · 바탕까지 다시 적어도 화면은 같지만, 바꿀 곳이 두 군데가 됩니다. 넓어지면 바뀔 선언만 넣습니다.
  • 가로 스크롤을 body { overflow-x: hidden; }⁠으로 감추면 밀리지는 않아도, 320에서 넘친 것이 오른쪽에서 잘린 채 남습니다. 넘친 상자를 찾아 고칩니다.
  • 걸음 4를 빠뜨려도 지금 두 페이지는 320에서 화면이 같습니다. 한 줄에 들지 않을 만큼 좁아지면 달라집니다 — flex-wrap이 없는 내비게이션은 링크가 줄어 글자가 링크 안에서 두 줄로 꺾이고, 있으면 둘째 링크가 통째로 다음 줄로 넘어갑니다.

폰 물음의 답은 ①입니다. min-width: 640px은 640px을 넣어 그때부터 한 줄입니다.

다시 볼 레슨: 모바일 먼저와 미디어 쿼리 · 유연한 그림 · 가로 스크롤 원인 찾기

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

HTML·CSS 목차로