두 폭 · 두 테마 점검은 완성한 할 일 화면을 좁은 창(375px) · 넓은 창(1280px)과 밝은 화면 · 어두운 화면이 만드는 네 화면에서 점검 목록으로 확인하는 일입니다. 만드는 동안에는 한 창 · 한 화면만 보게 되어, 다른 폭이나 어두운 화면에서만 깨지는 곳을 놓칩니다. 이 레슨으로 이 과목을 마치고, 이 화면에 동작을 붙이는 자바스크립트 과목으로 넘어갑니다.
이 레슨은 30분 안팎입니다. 네 화면을 하나씩 열어 점검 목록 다섯 줄을 대어 봅니다. 화면 하나를 마칠 때마다 멈췄다가 이어 해도 됩니다. 폰으로만 보고 있다면 예제의 잰 값을 읽으며 확인 문제로 따라옵니다.
앞 레슨에서 완성한 style.css — index.html은 그대로
/* style.css */
/* 1. 리셋 */
* {
box-sizing: border-box;
}
/* 2. 페이지 */
:root {
--bg: #f5f5f7;
--surface: #ffffff;
--text: #1d1d1f;
--muted: #6e6e73;
--line: #d2d2d7;
--accent: #005bb5;
--danger: #d70015;
color-scheme: light dark;
}
@media (
prefers-color-scheme: dark
) {
:root {
--bg: #121820;
--surface: #1d2633;
--text: #f1f4f8;
--muted: #a3adb8;
--line: #3a4552;
--accent: #9ac7ff;
--danger: #ff6b6b;
}
}
body {
margin: 0;
padding: 40px 16px;
background: var(--bg);
color: var(--text);
font-family:
system-ui,
sans-serif;
line-height: 1.6;
}
/* 3. 카드 */
.app {
max-width: 520px;
margin: 0 auto;
padding: 24px;
background: var(--surface);
border-radius: 12px;
box-shadow:
0 1px 3px rgb(0 0 0 / 0.1);
}
h1 {
margin: 0 0 8px;
font-size: 1.5rem;
}
/* 4. 한마디 */
.quote {
margin: 0 0 20px;
padding: 12px;
background: var(--bg);
border-radius: 8px;
color: var(--muted);
font-size: 0.875rem;
}
/* 5. 폼 */
#todo-form {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
#todo-input {
flex: 1;
padding: 10px 12px;
border: 1px solid var(--line);
border-radius: 8px;
background: var(--surface);
color: var(--text);
font-size: 0.9375rem;
font-family: inherit;
}
button {
padding: 10px 16px;
border: none;
border-radius: 8px;
background: var(--accent);
color: var(--surface);
font-size: 0.9375rem;
font-family: inherit;
cursor: pointer;
}
/* 6. 필터 */
.filters {
display: flex;
gap: 6px;
margin-bottom: 16px;
}
.filters button {
padding: 6px 12px;
background: var(--bg);
color: var(--text);
font-size: 0.875rem;
}
.filters button.active {
background: var(--text);
color: var(--surface);
}
/* 7. 목록 줄 */
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 4px;
border-bottom:
1px solid var(--line);
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list input {
width: 18px;
height: 18px;
cursor: pointer;
}
.text {
flex: 1;
cursor: pointer;
overflow-wrap: anywhere;
}
.delete {
padding: 4px 10px;
background: transparent;
color: var(--muted);
font-size: 1.125rem;
line-height: 1;
}
/* 8. 끝낸 상태 */
.done .text {
color: var(--muted);
text-decoration: line-through;
}
/* 9. 빈 안내 */
.empty {
padding: 32px 0;
color: var(--muted);
text-align: center;
}
/* 10. 아랫줄 */
.footer {
display: flex;
align-items: center;
justify-content:
space-between;
margin-top: 16px;
padding-top: 16px;
border-top:
1px solid var(--line);
}
.count {
margin: 0;
color: var(--muted);
font-size: 0.875rem;
}
.clear {
padding: 6px 12px;
background: transparent;
color: var(--muted);
font-size: 0.875rem;
}
/* 11. .sr-only */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
/* 12. 상태 */
button:hover {
background: var(--text);
color: var(--surface);
}
.filters button:hover {
background: var(--line);
color: var(--text);
}
.filters button.active:hover {
background: var(--text);
color: var(--surface);
}
.delete:hover {
background: var(--bg);
color: var(--danger);
}
.clear:hover {
background: var(--bg);
color: var(--text);
}
#todo-input:focus,
button:focus-visible,
#todo-list input:focus-visible {
outline:
2px solid var(--accent);
outline-offset: 1px;
}그림 준비 중
1네 화면 — 내용은 같고 색 · 배치만 다르다
| 화면 | 카드 | 바탕 |
|---|---|---|
| 375 · 밝은 화면 | 창을 채움 — 너비 343px | 연회색 |
| 375 · 어두운 화면 | 창을 채움 — 너비 343px | 짙은 남색 |
| 1280 · 밝은 화면 | 가운데 — 너비 520px | 연회색 |
| 1280 · 어두운 화면 | 가운데 — 너비 520px | 짙은 남색 |
글 · 단추 · 할 일 목록의 줄 수는 네 화면이 같습니다. 폭이 바꾸는 것은 카드 너비뿐이고(max-width: 520px — 브라우저 규칙 6), 밝은 · 어두운 화면이 바꾸는 것은 변수 값뿐입니다. 그래서 네 화면에서 내용이 달라 보이면 그것부터 깨진 곳입니다.
창 폭은 개발자 도구 기기 모드에서 Dimensions: Responsive를 고르고 너비 칸에 375와 1280을 적어 바꿉니다(meta viewport). 어두운 화면은 Rendering의 Emulate CSS media feature prefers-color-scheme 목록으로 흉내 냅니다(변수만 바꾸는 다크 모드). 끝나면 No emulation으로 되돌립니다.
2점검 목록 다섯 줄
네 화면마다 같은 다섯 줄을 대어 봅니다.
| 줄 | 볼 것 | 배운 곳 |
|---|---|---|
| 1. 가로 스크롤 | 페이지의 너비가 창의 너비와 같다 | 가로 스크롤 원인 찾기 |
| 2. 같은 내용 | 글 · 단추 · 줄 수가 네 화면에서 같다 | — |
| 3. 읽히는 색 | 개수 · 끝낸 줄 · 입력 칸 · 체크박스가 바탕에 묻히지 않는다 | 변수만 바꾸는 다크 모드 |
4. Tab으로 끝까지 | 열두 곳에 차례로 닿고, 간 곳마다 윤곽선이 보인다 | 키보드로 다니기 |
| 5. 검사기 | index.html의 Error 0 | 검사기로 틀린 HTML 찾기 |
- 1 · 2는 폭을, 3은 화면 색을, 4 · 5는 어느 화면에서나 한 번 봅니다.
Tab의 열두 곳은 입력 칸 · '추가' · 필터 셋 · 할 일 세 줄의 체크박스와×· '완료한 일 지우기'입니다. 여덟째가 끝낸 줄의 체크박스입니다.
3지금 보이는 것 → 자바스크립트 과목에서 붙는 동작
| 이름표 | 지금 | 자바스크립트 과목에서 |
|---|---|---|
#todo-form | 제출하면 다시 그려진다 | 친 글로 할 일을 더한다 |
#todo-list | 적어 둔 세 줄 | 할 일 목록에서 줄을 다시 그린다 |
.done | 둘째 줄에 붙어 있다 | 체크박스를 누를 때마다 붙였다 뗀다 |
.active | '전체'에 붙어 있다 | 누른 필터 단추로 옮기고 줄을 거른다 |
#count | 적어 둔 개수 | 남은 개수를 세어 쓴다 |
#quote | '오늘도 한 걸음씩.' | 한마디를 받아 오고, 못 받으면 이 글 |
그 과목의 코드는 이 이름표를 글자 그대로 부릅니다 — 개수 문단은 querySelector('#count')로 찾습니다. 이름표가 같아서, 그 과목의 코드를 줄마다 이 화면의 요소에 대어 읽을 수 있습니다.
4다음 걸음
- 자바스크립트 과목 — 처음부터 배우고, 12단원에서 이
index.html·style.css를 다시 엽니다. 그때 다리 레슨 'HTML을 처음 본다면'은 건너뛰고 '웹 페이지에서 돌리기'부터 합니다. - 이 과목이 이름만 둔 아홉 — 중첩(CSS 규칙 안에 규칙을 넣어 쓰기) · 컨테이너 쿼리(담은 상자의 폭에 맞추기) ·
@layer(규칙 묶음끼리 이기는 차례 정하기) ·clamp()(가장 작은 값과 가장 큰 값 사이에서 크기 정하기) ·dialog(대화 상자 요소) ·head의 메타데이터(공유 미리 보기 글 · 아이콘) ·srcset과picture('유연한 그림'에서 한 장으로 맞춘 그림을 화면 폭에 따라 다른 파일로 주기) · 웹 폰트와 아이콘 폰트('글자 꾸미기'에서 쓴 시스템 글꼴 대신 글꼴 파일을 받아 쓰기) · 옛 배치(float·<center>· 벤더 접두사 — 옛 코드를 읽을 때 만나는 방식). - 공개 — 만든 페이지를 다른 사람이 주소로 열게 하려면 파일을 웹 서버에 올립니다(배포). 이 화면처럼 HTML · CSS 파일만 있는 페이지는 파일을 올려 두는 것으로 공개됩니다.
예제
네 화면의 잰 값
375 · 밝은 화면과 1280 · 어두운 화면에서 잰 값입니다. 나머지 두 화면은 폭과 색을 하나씩 바꾼 것입니다.
375 · 밝은 화면 — 페이지 너비와 Tab 차례
<!-- index.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width"
/>
<title>오늘 할 일</title>
<link
rel="stylesheet"
href="style.css"
/>
</head>
<body>
<main class="app">
<h1>오늘 할 일</h1>
<p id="quote" class="quote">
오늘도 한 걸음씩.
</p>
<form id="todo-form">
<label
class="sr-only"
for="todo-input"
>
할 일
</label>
<input
id="todo-input"
type="text"
placeholder="예: 장보기"
autocomplete="off"
maxlength="100"
/>
<button type="submit">
추가
</button>
</form>
<div
id="filters"
class="filters"
>
<button
type="button"
data-filter="all"
class="active"
>
전체
</button>
<button
type="button"
data-filter="active"
>
진행 중
</button>
<button
type="button"
data-filter="done"
>
완료
</button>
</div>
<ul id="todo-list">
<li>
<input
type="checkbox"
aria-label="완료 표시"
/>
<span class="text">
우유 사기
</span>
<button
type="button"
class="delete"
aria-label="삭제"
>
×
</button>
</li>
<li class="done">
<input
type="checkbox"
aria-label="완료 표시"
checked
/>
<span class="text">
HTML·CSS 복습하기
</span>
<button
type="button"
class="delete"
aria-label="삭제"
>
×
</button>
</li>
<li>
<input
type="checkbox"
aria-label="완료 표시"
/>
<span class="text">
산책하기
</span>
<button
type="button"
class="delete"
aria-label="삭제"
>
×
</button>
</li>
</ul>
<p
id="empty"
class="empty"
hidden
>
할 일이 없습니다.
</p>
<footer class="footer">
<p
id="count"
class="count"
>
전체 3개 중 2개 남음
</p>
<button
type="button"
id="clear-done"
class="clear"
>
완료한 일 지우기
</button>
</footer>
</main>
</body>
</html>
/* style.css */
/* 1. 리셋 */
* {
box-sizing: border-box;
}
/* 2. 페이지 */
:root {
--bg: #f5f5f7;
--surface: #ffffff;
--text: #1d1d1f;
--muted: #6e6e73;
--line: #d2d2d7;
--accent: #005bb5;
--danger: #d70015;
color-scheme: light dark;
}
@media (
prefers-color-scheme: dark
) {
:root {
--bg: #121820;
--surface: #1d2633;
--text: #f1f4f8;
--muted: #a3adb8;
--line: #3a4552;
--accent: #9ac7ff;
--danger: #ff6b6b;
}
}
body {
margin: 0;
padding: 40px 16px;
background: var(--bg);
color: var(--text);
font-family:
system-ui,
sans-serif;
line-height: 1.6;
}
/* 3. 카드 */
.app {
max-width: 520px;
margin: 0 auto;
padding: 24px;
background: var(--surface);
border-radius: 12px;
box-shadow:
0 1px 3px rgb(0 0 0 / 0.1);
}
h1 {
margin: 0 0 8px;
font-size: 1.5rem;
}
/* 4. 한마디 */
.quote {
margin: 0 0 20px;
padding: 12px;
background: var(--bg);
border-radius: 8px;
color: var(--muted);
font-size: 0.875rem;
}
/* 5. 폼 */
#todo-form {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
#todo-input {
flex: 1;
padding: 10px 12px;
border: 1px solid var(--line);
border-radius: 8px;
background: var(--surface);
color: var(--text);
font-size: 0.9375rem;
font-family: inherit;
}
button {
padding: 10px 16px;
border: none;
border-radius: 8px;
background: var(--accent);
color: var(--surface);
font-size: 0.9375rem;
font-family: inherit;
cursor: pointer;
}
/* 6. 필터 */
.filters {
display: flex;
gap: 6px;
margin-bottom: 16px;
}
.filters button {
padding: 6px 12px;
background: var(--bg);
color: var(--text);
font-size: 0.875rem;
}
.filters button.active {
background: var(--text);
color: var(--surface);
}
/* 7. 목록 줄 */
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 4px;
border-bottom:
1px solid var(--line);
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list input {
width: 18px;
height: 18px;
cursor: pointer;
}
.text {
flex: 1;
cursor: pointer;
overflow-wrap: anywhere;
}
.delete {
padding: 4px 10px;
background: transparent;
color: var(--muted);
font-size: 1.125rem;
line-height: 1;
}
/* 8. 끝낸 상태 */
.done .text {
color: var(--muted);
text-decoration: line-through;
}
/* 9. 빈 안내 */
.empty {
padding: 32px 0;
color: var(--muted);
text-align: center;
}
/* 10. 아랫줄 */
.footer {
display: flex;
align-items: center;
justify-content:
space-between;
margin-top: 16px;
padding-top: 16px;
border-top:
1px solid var(--line);
}
.count {
margin: 0;
color: var(--muted);
font-size: 0.875rem;
}
.clear {
padding: 6px 12px;
background: transparent;
color: var(--muted);
font-size: 0.875rem;
}
/* 11. .sr-only */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
/* 12. 상태 */
button:hover {
background: var(--text);
color: var(--surface);
}
.filters button:hover {
background: var(--line);
color: var(--text);
}
.filters button.active:hover {
background: var(--text);
color: var(--surface);
}
.delete:hover {
background: var(--bg);
color: var(--danger);
}
.clear:hover {
background: var(--bg);
color: var(--text);
}
#todo-input:focus,
button:focus-visible,
#todo-list input:focus-visible {
outline:
2px solid var(--accent);
outline-offset: 1px;
}375px- 페이지의 너비375px
- 창의 너비375px
.app의 너비343px- 페이지의 Tab 차례할 일 → 추가 → 전체 → 진행 중 → 완료 → 완료 표시 → 삭제 → 완료 표시 → 삭제 → 완료 표시 → 삭제 → 완료한 일 지우기
1280 · 어두운 화면 — 카드 너비와 색
<!-- index.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width"
/>
<title>오늘 할 일</title>
<link
rel="stylesheet"
href="style.css"
/>
</head>
<body>
<main class="app">
<h1>오늘 할 일</h1>
<p id="quote" class="quote">
오늘도 한 걸음씩.
</p>
<form id="todo-form">
<label
class="sr-only"
for="todo-input"
>
할 일
</label>
<input
id="todo-input"
type="text"
placeholder="예: 장보기"
autocomplete="off"
maxlength="100"
/>
<button type="submit">
추가
</button>
</form>
<div
id="filters"
class="filters"
>
<button
type="button"
data-filter="all"
class="active"
>
전체
</button>
<button
type="button"
data-filter="active"
>
진행 중
</button>
<button
type="button"
data-filter="done"
>
완료
</button>
</div>
<ul id="todo-list">
<li>
<input
type="checkbox"
aria-label="완료 표시"
/>
<span class="text">
우유 사기
</span>
<button
type="button"
class="delete"
aria-label="삭제"
>
×
</button>
</li>
<li class="done">
<input
type="checkbox"
aria-label="완료 표시"
checked
/>
<span class="text">
HTML·CSS 복습하기
</span>
<button
type="button"
class="delete"
aria-label="삭제"
>
×
</button>
</li>
<li>
<input
type="checkbox"
aria-label="완료 표시"
/>
<span class="text">
산책하기
</span>
<button
type="button"
class="delete"
aria-label="삭제"
>
×
</button>
</li>
</ul>
<p
id="empty"
class="empty"
hidden
>
할 일이 없습니다.
</p>
<footer class="footer">
<p
id="count"
class="count"
>
전체 3개 중 2개 남음
</p>
<button
type="button"
id="clear-done"
class="clear"
>
완료한 일 지우기
</button>
</footer>
</main>
</body>
</html>
/* style.css */
/* 1. 리셋 */
* {
box-sizing: border-box;
}
/* 2. 페이지 */
:root {
--bg: #f5f5f7;
--surface: #ffffff;
--text: #1d1d1f;
--muted: #6e6e73;
--line: #d2d2d7;
--accent: #005bb5;
--danger: #d70015;
color-scheme: light dark;
}
@media (
prefers-color-scheme: dark
) {
:root {
--bg: #121820;
--surface: #1d2633;
--text: #f1f4f8;
--muted: #a3adb8;
--line: #3a4552;
--accent: #9ac7ff;
--danger: #ff6b6b;
}
}
body {
margin: 0;
padding: 40px 16px;
background: var(--bg);
color: var(--text);
font-family:
system-ui,
sans-serif;
line-height: 1.6;
}
/* 3. 카드 */
.app {
max-width: 520px;
margin: 0 auto;
padding: 24px;
background: var(--surface);
border-radius: 12px;
box-shadow:
0 1px 3px rgb(0 0 0 / 0.1);
}
h1 {
margin: 0 0 8px;
font-size: 1.5rem;
}
/* 4. 한마디 */
.quote {
margin: 0 0 20px;
padding: 12px;
background: var(--bg);
border-radius: 8px;
color: var(--muted);
font-size: 0.875rem;
}
/* 5. 폼 */
#todo-form {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
#todo-input {
flex: 1;
padding: 10px 12px;
border: 1px solid var(--line);
border-radius: 8px;
background: var(--surface);
color: var(--text);
font-size: 0.9375rem;
font-family: inherit;
}
button {
padding: 10px 16px;
border: none;
border-radius: 8px;
background: var(--accent);
color: var(--surface);
font-size: 0.9375rem;
font-family: inherit;
cursor: pointer;
}
/* 6. 필터 */
.filters {
display: flex;
gap: 6px;
margin-bottom: 16px;
}
.filters button {
padding: 6px 12px;
background: var(--bg);
color: var(--text);
font-size: 0.875rem;
}
.filters button.active {
background: var(--text);
color: var(--surface);
}
/* 7. 목록 줄 */
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 4px;
border-bottom:
1px solid var(--line);
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list input {
width: 18px;
height: 18px;
cursor: pointer;
}
.text {
flex: 1;
cursor: pointer;
overflow-wrap: anywhere;
}
.delete {
padding: 4px 10px;
background: transparent;
color: var(--muted);
font-size: 1.125rem;
line-height: 1;
}
/* 8. 끝낸 상태 */
.done .text {
color: var(--muted);
text-decoration: line-through;
}
/* 9. 빈 안내 */
.empty {
padding: 32px 0;
color: var(--muted);
text-align: center;
}
/* 10. 아랫줄 */
.footer {
display: flex;
align-items: center;
justify-content:
space-between;
margin-top: 16px;
padding-top: 16px;
border-top:
1px solid var(--line);
}
.count {
margin: 0;
color: var(--muted);
font-size: 0.875rem;
}
.clear {
padding: 6px 12px;
background: transparent;
color: var(--muted);
font-size: 0.875rem;
}
/* 11. .sr-only */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
/* 12. 상태 */
button:hover {
background: var(--text);
color: var(--surface);
}
.filters button:hover {
background: var(--line);
color: var(--text);
}
.filters button.active:hover {
background: var(--text);
color: var(--surface);
}
.delete:hover {
background: var(--bg);
color: var(--danger);
}
.clear:hover {
background: var(--bg);
color: var(--text);
}
#todo-input:focus,
button:focus-visible,
#todo-list input:focus-visible {
outline:
2px solid var(--accent);
outline-offset: 1px;
}1280px- 페이지의 너비1280px
.app의 너비520pxbody의background-colorrgb(18, 24, 32).count의 글자색rgb(163, 173, 184)
- 두 화면 모두 페이지의 너비가 창의 너비와 같아 가로 스크롤이 없습니다.
- 어두운 화면의 개수 글자는
--muted의 어두운 값입니다. 바탕이 바뀐 만큼 글자도 밝아졌습니다.
자주 틀리는 곳
틀린 생각: 만들 때 보던 한 폭 · 한 화면에서 맞으면 다 맞다.
<div class="app">
<p class="count">
전체 3개 중 2개 남음
</p>
</div>
:root {
--surface: #ffffff;
}
@media (
prefers-color-scheme: dark
) {
:root {
--surface: #1d2633;
}
}카드 바탕은 변수로, 개수 글자는 값으로 칠합니다.
.app {
background: var(--surface);
}
.count {
color: #1d1d1f;
}.count의 글자색rgb(29, 29, 31).app의background-colorrgb(29, 38, 51)
개수 글자색을 변수 대신 값으로 적었습니다. 밝은 화면에서는 흰 카드 위 짙은 글자라 멀쩡하지만, 어두운 화면에서는 짙은 남색 카드 위 짙은 글자가 되어 묻힙니다.
맞는 규칙: 점검 목록은 네 화면마다 댑니다. 색은 변수로 칠해 두 화면에서 함께 바뀌게 합니다.
틀린 생각: 마우스로 눌러 보아 되면 키보드도 된다.
<footer class="footer">
<p id="count">
전체 3개 중 2개 남음
</p>
<div class="clear">
완료한 일 지우기
</div>
</footer>
<button type="button">
추가
</button>- 페이지의 Tab 차례추가
지우기를 div로 만들었습니다. CSS로 단추처럼 칠할 수는 있지만 Tab이 닿지 않아, Tab 차례에 '추가'만 있습니다.
맞는 규칙: Tab으로 끝까지 가 보며 누를 것마다 닿는지, 간 곳마다 윤곽선이 보이는지 봅니다(브라우저 규칙 3). 누르는 것은 button으로 만듭니다.
틀린 생각: HTML은 앞 레슨에서 검사기를 지났으니 다시 볼 필요가 없다.
<ul id="todo-list">
<li class="done>
<span class="text">
산책하기
</span>
</li>
</ul>- Error2~3줄No space between attributes.
- Error3줄Quote “"” in attribute name. Probable cause: Matching quote missing somewhere earlier.
- Error3줄Attribute “text"” not allowed on element “li” at this point.
- Error5줄Stray end tag “span”.
li의 보이는 글산책하기
CSS를 맞추다 class="done"의 닫는 따옴표를 지웠습니다. 화면에는 '산책하기'가 그대로 보여 지나치기 쉽지만, 끝낸 줄의 이름표가 깨져 취소선이 사라집니다.
맞는 규칙: 점검할 때마다 index.html을 검사기에 다시 넣습니다. Error는 첫 줄(2~3줄)부터 봅니다.
확인 문제
1. 어두운 화면에서 할 일 화면의 입력 칸 바탕은 어떤 색일까요?
- ① 흰색(
#ffffff) 그대로 - ② 카드와 같은 짙은 색(
#1d2633) - ③ 페이지 바탕과 같은 색(
#121820)
힌트
style.css의 5. 폼 구역에서 #todo-input의 background를 찾아보세요.
힌트 둘
그 값이 어느 변수인지 보고, 2. 페이지 구역의 어두운 화면 조건 블록에서 그 변수의 값을 찾습니다.
정답
② — 입력 칸 바탕은 var(--surface)이고, 어두운 화면에서 --surface는 #1d2633입니다.
<input
id="todo-input"
aria-label="할 일"
/>
:root {
--surface: #ffffff;
}
@media (
prefers-color-scheme: dark
) {
:root {
--surface: #1d2633;
}
}
#todo-input {
background: var(--surface);
}#todo-input의background-colorrgb(29, 38, 51)
- 변수로 칠한 곳은 변수 값이 바뀌면 함께 바뀝니다. 카드도
var(--surface)라 입력 칸과 카드가 같은 색입니다. - ①은 입력 칸을 브라우저가 늘 흰색으로 그린다고 본 것입니다. 이 화면은 바탕을 변수로 정했습니다.
- ③은
--bg와 헷갈린 것입니다.--bg는 페이지 바탕 · 한마디 띠 · 필터 단추에 씁니다.
2. 375px 창에서 카드 .app의 너비가 343px인 까닭을 셈으로 채웁니다. body의 padding: 40px 16px;에서 좌우 안쪽 여백은 ____px이고, 375 − ____ × 2 = 343입니다. ____에 들어갈 수를 쓰세요.
힌트
값을 둘 적은 짧게 적기에서 첫째 값과 둘째 값이 각각 어느 방향인지 떠올리세요.
정답
16 — 값 둘이면 첫째가 위아래, 둘째가 좌우입니다.
<div class="app">
<h1>오늘 할 일</h1>
</div>
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 40px 16px;
}
.app {
max-width: 520px;
margin: 0 auto;
padding: 24px;
}375pxbody의padding-left16px.app의 너비343px
- 좁은 창에서는
max-width보다 창이 좁아, 카드가body의 내용 칸 375 − 32 = 343을 채웁니다. 카드의 안쪽 여백 24는 너비를 적지 않은 블록이라 343 안에 듭니다(브라우저 규칙 6). 리셋(border-box)은 넓은 창에서max-width520이 테두리까지가 되게 합니다 — 리셋이 없으면 1280에서 568입니다. - 흔한 오답은 40입니다. 40은 위아래 안쪽 여백입니다(여백 짧게 적기).
3. 플로우 카페 메뉴 카드를 375px 창에서 열었더니 가로 스크롤이 생겼습니다. 무엇을 고칠까요? 고친 규칙을 쓰세요.
<div class="menu-card">
<h2>플로우 카페 메뉴</h2>
<p>커피 4000원</p>
</div>
.menu-card {
width: 520px;
padding: 16px;
}- 페이지의 너비560px
- 창의 너비375px
힌트
점검 목록 1줄에 걸렸습니다. 카드의 너비를 정한 선언을 보세요.
힌트 둘
할 일 화면의 카드는 넓은 창에서만 520px이고, 좁은 창에서는 창을 채웠습니다. 어떤 속성이었는지 떠올려 보세요.
정답
width: 520px을 max-width: 520px로 바꿉니다.
<div class="menu-card">
<h2>플로우 카페 메뉴</h2>
<p>커피 4000원</p>
</div>
.menu-card {
max-width: 520px;
padding: 16px;
}375px- 페이지의 너비375px
- 창의 너비375px
width는 창이 좁아도 520px을 지켜, 바깥 여백 8과 안쪽 여백 32까지 페이지가 560px이 되었습니다.max-width는 넓을 때만 막고 좁으면 창에 맞춥니다.- 흔한 오답은
body에overflow-x: hidden을 주는 것입니다. 가로 스크롤 막대만 사라지고 카드 오른쪽은 창 밖에서 잘립니다.
컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요.
완성한 두 파일을 열고 기기 모드 375 · 1280과 Rendering의 밝은 · 어두운 흉내를 바꿔 가며 네 화면에 점검 목록 다섯 줄을 대어 봅니다. 마지막으로 W3C 검사기의 칸의 글을 모두 지우고(전체 선택 → 지우기) index.html을 붙여 넣어 Error 0을 봅니다.