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 | 우리 CSS | 0-1-0 | 2 | 1fr |
조건 블록 .shots · repeat(3, 1fr) | 우리 CSS | 0-1-0 | 1 |
차례 칸은 규칙 차례(조건 블록 안 .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의 너비150pximg의 높이400px
- (가)
max-width: 100%는 너비만 칸의 내용 칸 150px로 줄입니다. 높이는 HTML의height="400"그대로라, 300 × 400 사진이 150 × 400 칸에 맞춰 가로로 눌려 찌그러집니다(브라우저 규칙 6). - (나)
height: auto를 더하면 높이를 원본 비율대로 셈합니다 — 150 × 400 ÷ 300 = 200px입니다.
img {
height: auto;
}img의 너비150pximg의 높이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. 내용 칸 | width | 220 |
| 2. 안쪽 여백 더하기 | 220 + 12 × 2 | 244 |
| 3. 테두리 더하기 | 244 + 3 × 2 | 250 |
| 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같은 폴더 안에 두지 못해../가 실제 폴더와 다르게 풀립니다. 컴퓨터에서 폴더를 만들어 확인해 보세요.
문제 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의 너비318pximg의 높이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을 넣어 그때부터 한 줄입니다.
다시 볼 레슨: 모바일 먼저와 미디어 쿼리 · 유연한 그림 · 가로 스크롤 원인 찾기