14단원 '겹치고 고정하기: position'의 다섯 레슨에서 10문제를 내고, 2 · 12 · 13단원에서 3문제를 섞었습니다. 앞 단원 문제가 어느 레슨인지는 정답을 펼치면 보입니다. 값이나 기호, 고친 줄은 종이에 끝까지 쓴 뒤 정답을 펼치세요. 막히면 정답 앞의 힌트를 먼저 펼칩니다. 점수는 매기지 않습니다.
결과를 묻는 문제의 결과 화면과 잰 값은 정답을 펼치면 보입니다. 결과 화면은 페이지 안에서 굴러가지 않습니다 — 내린 뒤의 자리를 묻는 문제는 잰 값으로 맞춰 보고, 컴퓨터가 있으면 문제의 HTML과 CSS를 파일로 저장해 브라우저로 열어 직접 내려 봅니다. 개발자 도구 Computed 창에서 position · top · z-index 값을 볼 수 있습니다. 결과는 모두 크롬 기준입니다.
이 단원을 이미 안다면 1 · 2 · 3 · 4 · 6 · 7번을 먼저 풀어 보세요. 건너뛸지 볼 때는 힌트를 펴지 않고 풉니다. 다 맞히면 이 단원은 건너뛰어도 됩니다. 틀린 문제와 힌트를 펴고 맞힌 문제는 정답 끝의 '다시 볼 레슨'으로 갑니다. 끝의 두 문제(12 · 13번)는 직접 만들어 보는 문제라, 건너뛸지 가릴 때는 풀지 않아도 됩니다. 11번까지 풀고 쉬었다가 12번부터 이어 풀어도 됩니다. ⟨컴퓨터⟩가 붙은 문제는 컴퓨터에서 파일을 만들어 풉니다. 폰으로만 본다면 그 문제 끝의 폰 물음 하나로 대신합니다.
문제 1
레시피 노트 조리 순서의 둘째 줄을 흐름에서 빼 보았습니다. top · left는 적지 않았습니다. 결과 화면은 어떻게 보일까요? 보기 셋 가운데 고르세요.
<p>밥 볶기</p>
<p class="x">김치 넣기</p>
<p>달걀 올리기</p>
.x {
position: absolute;
}
힌트
세 줄을 위에서부터 차례로 그리고, 둘째 줄에 준 선언이 그 줄에 무슨 일을 하는지 적어 보세요.
힌트 둘
셋째 줄에도 무슨 일이 생기는지 보세요. 흐름에서 빠진 상자는 원래 자리를 남기지 않습니다. top 등을 적지 않으면 원래 있던 자리에 떠 있습니다.
정답
③ — 첫 줄 아래에서 둘째 줄과 셋째 줄 글자가 겹칩니다.
position: absolute인 둘째 줄은 흐름에서 빠져 원래 자리를 남기지 않습니다. 그래서 셋째 줄이 그 자리로 올라옵니다(브라우저 규칙 8).- 둘째 줄은
top·left가 없어 원래 있던 자리에 그대로 떠 있습니다. 올라온 셋째 줄과 같은 자리라 두 글자가 겹칩니다. - ①은
top을 적지 않으면absolute도 아무 일을 하지 않는다고 본 것입니다. 자리를 비우는 일은absolute한 줄로 이미 일어납니다. - ②는
absolute상자가 늘 맨 위 왼쪽 모서리로 간다고 본 것입니다. 모서리로 가려면top·left를 적어야 합니다.
다시 볼 레슨: 일반 흐름과 position
문제 2
짝마다 두 코드의 화면이 같은지 다른지 쓰세요. 다르면 어디가 다른지도 한 줄로 쓰세요. 셋 모두 같은 답이 나와도 됩니다.
(가)
<div class="a">가</div>
<div>나</div>
.a {
position: relative;
}
<div class="a">가</div>
<div>나</div>
(나)
<div class="a">가</div>
<div>나</div>
.a {
position: relative;
top: 20px;
}
<div class="a">가</div>
<div>나</div>
.a {
margin-top: 20px;
}
(다)
<p>본문</p>
<div class="cover"></div>
.cover {
position: fixed;
inset: 0;
background-color: #d2d2d7;
}
<p>본문</p>
<div class="cover"></div>
.cover {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #d2d2d7;
}
힌트
짝마다 바뀐 줄을 찾고, '가'가 움직이는지와 '나'가 따라 움직이는지를 따로 적어 보세요.
힌트 둘
relative는 원래 자리를 남긴 채 그려진 자리만 옮깁니다. inset은 네 방향을 한 줄에 적는 짧게 적기입니다.
정답
(가) 같다 · (나) 다르다 — 앞 코드는 '가'만 내려와 '나'와 겹치고, 뒤 코드는 '나'도 함께 내려간다 · (다) 같다
- (가)
position: relative는top·left등을 적지 않으면 상자를 옮기지 않습니다. 기준 상자가 될 준비만 합니다. - (나)
relative의top: 20px은 '가'를 원래 자리에서 20px 아래에 그리지만, 원래 자리는 그대로 남아 '나'는 움직이지 않습니다 — 내려온 '가'가 '나'와 겹칩니다. 바깥 여백은 자리 자체를 늘려 '나'도 함께 밀어 냅니다(브라우저 규칙 8). - (다)
inset: 0은top·right·bottom·left를 한꺼번에 0으로 정하는 짧게 적기입니다. 두 덮개 모두 창 네 변까지 덮어 본문을 가립니다. - (가) 다르다는
relative만 주어도 상자가 움직인다고 본 것입니다. - (나) 같다는
relative로 옮기면 뒤 상자도 밀린다고 본 것입니다. - (다) 다르다는
inset한 줄이 한 방향만 정한다고 본 것입니다(짧게 적기는 적은 칸만 바꾼다는 생각과 같은 뿌리).
다시 볼 레슨: 일반 흐름과 position
문제 3
동아리 공연 게시판입니다. 글 머리의 '거리 공연' 옆에 '마감' 꼬리표를 absolute로 겹쳤습니다. 꼬리표 .tag의 기준 상자는 어느 것일까요? 기호를 쓰세요.
<section class="board">
<article>
<div class="head">
<p>
거리 공연
<span class="tag">
마감
</span>
</p>
</div>
</article>
</section>
.board {
position: relative;
padding: 24px;
}
.head {
position: relative;
padding: 12px;
}
.tag {
position: absolute;
top: 0;
right: 0;
}
- ㉠
section게시판 - ㉡
article - ㉢
div.head - ㉣
p거리 공연 - ㉤ 처음 화면(페이지를 열었을 때 창에 보이는 첫 화면)
힌트
.tag부터 바깥 요소까지 나무를 그리고, 요소마다 position 값을 적어 보세요.
힌트 둘
기준 상자는 position이 static이 아닌 가장 가까운 조상입니다. 위로 올라가다 처음 만나는 그런 요소에서 멈춥니다.
정답
㉢ — div.head입니다.
p의positionstatic.board의 위 자리8px.head의 위 자리32px.tag의 위 자리32px
.tag에서 바깥으로 올라가면p(static) →div.head(relative)에서 멈춥니다.top: 0이라 꼬리표 위 가장자리가.head의 위 가장자리(32px)와 같습니다(브라우저 규칙 8).p의position은static입니다..head의relative를 안쪽 요소가 물려받지 않습니다.- ㉣을 골랐다면
absolute가 바로 위 부모를 기준으로 한다고 본 것입니다(부모 기준이라는 생각). 부모p는static이라 지나칩니다. - ㉠을 골랐다면 바깥에서 처음
relative를 준 요소가 기준이라고 본 것입니다. 찾는 방향은 안에서 바깥으로, 가장 가까운 쪽이 이깁니다. - ㉤을 골랐다면
absolute가 늘 페이지를 기준으로 한다고 본 것입니다. 처음 화면은static이 아닌 조상이 하나도 없을 때입니다.
다시 볼 레슨: 기준 상자와 absolute · 물려받기
문제 4
플로우 카페 메뉴 카드 오른쪽 위에 '인기' 꼬리표를 붙였습니다. 카드에는 테두리 4px과 안쪽 여백 20px이 있습니다. (가) 꼬리표의 위 가장자리는 카드의 위 테두리 바깥선에서 몇 px 아래에 놓일까요? (나) 꼬리표의 오른쪽 가장자리는 카드의 오른쪽 테두리 바깥선에서 몇 px 안쪽에 놓일까요? 숫자만 쓰세요.
<div class="item">
<span class="hot">인기</span>
밀크티 5000원
</div>
.item {
position: relative;
width: 200px;
padding: 20px;
border: 4px solid #6e6e73;
}
.hot {
position: absolute;
top: 8px;
right: 8px;
}
힌트
카드의 네 겹(내용 칸 · 안쪽 여백 · 테두리 · 바깥 여백)을 그리고, top: 8px을 어느 선에서부터 재는지 표시해 보세요.
힌트 둘
top · right는 기준 상자의 안쪽 여백 바깥 가장자리, 곧 테두리 안쪽 선에서 잽니다.
정답
(가) 12 · (나) 12
.item의 위 자리8px.hot의 위 자리20px.item의 오른쪽 끝256px.hot의 오른쪽 끝244px
top: 8px은 카드의 테두리 안쪽 선(안쪽 여백 바깥 가장자리)에서 잽니다. 테두리 4px 안쪽에서 8px 더 내려와, 바깥선에서 4 + 8 = 12px입니다. 오른쪽도 같아 12px입니다(브라우저 규칙 8).- 흔한 오답은 32입니다. 내용 칸에서 잰다고 보고 테두리 4 · 안쪽 여백 20 · 8을 모두 더한 것입니다. 안쪽 여백은 꼬리표가 겹쳐 앉는 자리입니다.
- 8은 테두리 바깥선에서 잰다고 본 것입니다. 테두리는 기준 상자의 바깥 겹이라 그 안쪽에서 잽니다.
다시 볼 레슨: 기준 상자와 absolute · 상자 네 겹
문제 5
여행 사진 목록의 대표 사진 칸이 세 열을 차지하게 했습니다. 대표 사진 칸 .best의 너비는 몇 px일까요? 숫자만 쓰세요.
<div class="photos">
<div class="best">바다</div>
<div>시장</div>
<div>등대</div>
</div>
.photos {
display: grid;
grid-template-columns:
repeat(4, 60px);
gap: 8px;
}
.best {
grid-column: span 3;
}
힌트
네 열 격자를 종이에 그리고, .best가 차지하는 자리를 칠해 보세요.
힌트 둘
칠한 세 열 사이에 무엇이 끼어 있는지 표시해 보세요.
정답
196입니다.
.best의 너비196px.photos div:nth-child(2)의 너비60px
span 3은 세 열과 그 사이 간격 둘을 함께 차지합니다 — 60 × 3 + 8 × 2 = 196px입니다(브라우저 규칙 7).- 흔한 오답은 180입니다. 열 셋만 더하고 사이 간격을 빠뜨린 것입니다.
다시 볼 레슨: 칸 여러 개 차지하기
문제 6
김치볶음밥 페이지의 '재료' 제목을 굴려도 창 맨 위에 붙어 있게 했습니다. .sec는 창 맨 위에서 200px 아래에서 시작하고 높이가 500px입니다. 아래 셋에서 제목 .head의 창 위 자리는 몇 px일까요? 숫자만 쓰세요(위로 벗어나면 음수).
- (가) 페이지를 300px 내린 뒤
- (나) 페이지를 680px 내린 뒤
- (다)
.sec규칙에overflow: hidden;을 더하고 300px 내린 뒤
<section class="sec">
<div class="head">재료</div>
</section>
body {
margin: 0;
height: 2000px;
}
.sec {
margin-top: 200px;
height: 500px;
}
.head {
position: sticky;
top: 0;
height: 50px;
}
힌트
내린 거리마다 .sec의 위 · 아래 끝이 창 위에서 몇 px인지 먼저 적고, 제목이 붙을 자리와 견줘 보세요.
힌트 둘
sticky는 담은 상자 안에서만 붙습니다. 담은 상자의 끝이 올라오면 같이 올라갑니다. overflow: hidden을 준 상자는 제 안의 굴림 범위가 되어, 머리글이 그 상자를 기준으로 붙으려 합니다.
정답
(가) 0 · (나) −30 · (다) −100
.sec의 창 위 자리-100px.head의 창 위 자리0px
(나) 같은 코드를 680px 내린 뒤입니다.
/* 같은 코드, 680px 내림 */.sec의 창 위 자리-480px.head의 창 위 자리-30px
(다) .sec에 overflow: hidden을 더하고 300px 내린 뒤입니다.
.sec {
overflow: hidden;
}.head의 창 위 자리-100px
| 내린 거리 | .sec 위 · 아래 끝 | 제목 |
|---|---|---|
| 300 | −100 · 400 | 붙는 자리 0 — 아래 끝 400까지 넉넉해 0 |
| 680 | −480 · 20 | 0에 붙으면 아래 끝 50이 20을 넘음 → 20 − 50 = −30 |
300 · overflow: hidden | −100 · 400 | 붙지 않고 .sec와 함께 올라감 → 원래 자리 −100 |
- (가)
sticky는 원래 자리를 남긴 채, 원래 자리가 창 맨 위를 지나 올라가면 거기에 붙습니다(브라우저 규칙 8). - (나) 담은 상자
.sec의 아래 끝이 창 위 20px까지 올라오면, 제목은 그 안에 남으려고 함께 올라갑니다. 흔한 오답 0은sticky가fixed처럼 끝까지 붙어 있다고 본 것입니다. - (다)
overflow: hidden을 준.sec가 자르는 상자라, 제목은 페이지가 아니라.sec안의 굴림에 붙으려 합니다. 그런데.sec는 굴러가지 않으니, 제목은 붙지 않고.sec와 함께 올라가 원래 자리 −100입니다. 흔한 오답 0은overflow가 붙는 일과 상관없다고 본 것입니다.
다시 볼 레슨: sticky 머리글과 z-index · overflow: hidden으로 자르기
문제 7
플로우 카페 찾아오는 길 지도 위에 빨간 핀을 겹치려고, 핀을 바깥 여백으로 끌어 올리고 z-index를 크게 줬습니다. (가) 핀 가운데 자리에서 맨 위에 그려지는 것은 지도와 핀 가운데 무엇일까요? (나) 핀이 지도 위에 오게 하려면 .pin 규칙에 선언 한 줄을 더합니다. 그 줄을 쓰세요.
<div class="map">지도</div>
<div class="pin">핀</div>
.map {
position: relative;
z-index: 2;
height: 80px;
background-color: #d2d2d7;
}
.pin {
margin-top: -40px;
z-index: 5;
height: 40px;
background-color: #d70015;
}
힌트
두 상자의 선언을 표로 나란히 적어 보세요 — position · z-index · 바깥 여백.
힌트 둘
이 과목에서 z-index는 position을 준 상자에 씁니다. position이 없는 상자의 z-index는 쌓는 차례를 바꾸지 못합니다.
정답
(가) 지도 · (나) position: relative;
.pin의positionstatic.pin의 맨 위 요소div.map
.pin에는position이 없어z-index: 5가 쌓는 차례에 쓰이지 않습니다.position을 준.map이 흐름 안의.pin보다 위에 그려집니다(브라우저 규칙 8).- (나)
.pin에position: relative를 더하면 두 상자 모두position이 있어,z-index가 큰.pin(5)이.map(2) 위로 올라옵니다.
.pin {
position: relative;
}.pin의 맨 위 요소div.pin
- (가)에서 흔한 오답은 핀입니다.
z-index가 크면 무엇이든 위에 온다고 본 것입니다. - (나)에서
z-index를 9999로 키우는 것은 흔한 오답입니다.position이 없으면 숫자를 아무리 키워도 그대로입니다.
다시 볼 레슨: sticky 머리글과 z-index
문제 8
하고 싶은 일에 쓸 이름을 쓰세요.
- (가) 상자를 흐름에서 빼고, 굴려도 창의 같은 자리에 두는
position값 - (나) 원래 자리를 남긴 채, 굴리다 정한 경계에 닿으면 거기 붙는
position값 - (다) 겹친 상자 가운데 어느 것을 위에 그릴지 정하는 CSS 속성
- (라) 화면에서만 숨기고 읽는 이름은 남기는, 여섯 줄짜리 규칙의 선택자
힌트
(가)(나)는 position 값 넷 가운데 둘, (다)는 붙는 머리글을 카드 위로 올린 속성, (라)는 할 일 화면의 숨긴 라벨에 쓴 클래스입니다.
정답
받는 답: (가) fixed · (나) sticky · (다) z-index · (라) .sr-only
- (라)는 물음이 선택자라 점을 붙입니다. 점 없는
sr-only는 클래스 이름이라 다른 답입니다 — 규칙의 선택자로 쓰면sr-only라는 태그를 고르려 해 아무것도 고르지 않습니다. - 틀리는 꼴 — (가)
absolute도 흐름에서 빠지지만 기준 상자를 따라 굴리면 함께 올라갑니다. (나)relative는 원래 자리를 남기지만 붙지 않습니다. (라)hidden속성이나display: none은 화면과 함께 읽는 이름도 지웁니다.
다시 볼 레슨: 일반 흐름과 position · sticky 머리글과 z-index · .sr-only 한 줄씩
문제 9
레시피 노트 내비게이션 줄입니다. 링크 둘을 flex로 나란히 놓고, '새 글' 꼬리표만 absolute로 오른쪽 위에 겹쳤습니다. flex 항목을 모두 고르세요. 기호를 다 쓰세요.
<nav class="bar">
<a href="index.html">목록</a>
<span class="new">새 글</span>
<a href="tips.html">
요리 팁 <b>3</b>
</a>
</nav>
.bar {
position: relative;
display: flex;
gap: 16px;
}
.bar a {
width: 80px;
}
.new {
position: absolute;
top: 0;
right: 0;
}
- ㉠
a목록 - ㉡
span새 글 - ㉢
a요리 팁 - ㉣
b3
힌트
display: flex가 걸린 요소의 자식을 나무로 그려 보세요.
힌트 둘
직계 자식을 먼저 적고, 그 가운데 흐름에서 빠진 것이 있는지 표시해 보세요.
정답
㉠ ㉢ — 링크 둘입니다.
.bar > a의 고른 글목록 · 요리 팁.bar > a:last-child의 왼쪽 자리104px.new의positionabsolute
- flex 항목은
.bar의 직계 자식 가운데 흐름에 남은 것입니다.span.new는 직계 자식이지만absolute로 흐름에서 빠져 항목이 아닙니다 — 그래서 둘째 링크가 첫 링크 바로 뒤 8 + 80 + 16 = 104px에서 시작하고, 꼬리표 몫의gap도 생기지 않습니다(브라우저 규칙 7 · 8). - ㉣
b는 둘째 링크 안의 손자라 항목이 아닙니다. - ㉠ ㉡ ㉢을 골랐다면 흐름에서 빠진 상자도 항목이라고 본 것입니다.
- ㉣까지 골랐다면 flex가 그 안 모든 요소에 닿는다고 본 것입니다(flex가 후손까지라는 생각).
다시 볼 레슨: flex는 부모에 · .sr-only 한 줄씩
문제 10
여행 일정 페이지의 검색 칸입니다. 라벨은 칸 위 줄에 따로 두고, 라벨 글을 줄을 바꾸고 빈칸을 여럿 넣어 적었습니다. (가) 화면에 보이는 라벨 글을 쓰세요. 줄이 나뉘면 ' / '로 이어 씁니다. (나) 입력 칸의 읽는 이름을 쓰세요.
<label for="city">
가고 싶은
도시 이름
</label>
<input id="city" />
label {
display: block;
}
힌트
라벨 안 글자 사이의 빈칸 · 줄바꿈을 기호로 표시해 보세요.
힌트 둘
브라우저가 그릴 때 그 빈칸 · 줄바꿈을 어떻게 하는지 떠올려 보세요.
정답
(가) 가고 싶은 도시 이름 · (나) 가고 싶은 도시 이름
label의 보이는 글가고 싶은 도시 이름input의 읽는 이름가고 싶은 도시 이름
- 라벨 안의 줄바꿈과 여러 빈칸은 나무에 글로 남지만, 그릴 때 이어진 빈칸이 하나로 합쳐집니다(브라우저 규칙 2). 화면에는 한 줄로 '가고 싶은 도시 이름'이 보이고, 읽는 이름도 같은 글입니다.
- 흔한 오답은 '가고 싶은 / 도시 이름'처럼 친 대로 줄과 빈칸을 남긴 것입니다(친 대로 나온다는 생각).
다시 볼 레슨: 공백 규칙과 특수 문자 · label로 칸에 이름 붙이기
문제 11
여행 일정의 숙소 카드 둘에 '예약 완료' 꼬리표를 카드 오른쪽 위에 겹치려 했습니다. 그런데 꼬리표 둘이 모두 페이지 오른쪽 위 한자리에 겹쳐 있습니다. 개발자 도구에서 꼬리표를 골라 보니 Styles 창의 선언에는 취소선도 경고 표시도 없고, Computed 창의 top은 8px입니다. 어느 규칙에 무엇을 더해야 할까요? 더할 줄을 쓰세요.
<div class="room">
바닷가 민박
<span class="done">
예약 완료
</span>
</div>
<div class="room">
산속 펜션
<span class="done">
예약 완료
</span>
</div>
.room {
margin-bottom: 12px;
padding: 16px;
border: 1px solid #d2d2d7;
}
.done {
position: absolute;
top: 8px;
right: 8px;
}힌트
찾는 차례대로 1번부터 지워 가세요. 5번에서는 꼬리표에서 나무를 따라 바깥으로 올라가며 Computed 창의 position을 봅니다.
힌트 둘
absolute 상자는 position이 static이 아닌 가장 가까운 조상을 기준으로 놓입니다. 그런 조상이 없으면 처음 화면이 기준입니다.
정답
받는 답: .room 규칙에 position: relative;를 더합니다.
<div class="room">
바닷가 민박
<span class="done">
예약 완료
</span>
</div>
<div class="room">
산속 펜션
<span class="done">
예약 완료
</span>
</div>
.room {
position: relative;
margin-bottom: 12px;
padding: 16px;
border: 1px solid #d2d2d7;
}
.done {
position: absolute;
top: 8px;
right: 8px;
}.room의positionrelative.done의 배치 위 자리8px.room:last-child .done의 배치 위 자리8px
찾는 차례 5번에서 찾습니다.
- 1번 · 3번 — 꼬리표가 페이지 오른쪽 위로 옮겨 갔으니 파일도 닿았고
.done규칙도 닿았습니다. - 2번 — Elements 패널에서 꼬리표 둘은 저마다 제 카드
div.room안에 있습니다. - 4번 — 선언에 취소선도 경고 표시도 없습니다. 알아들었고 이겼습니다.
- 5번 — 꼬리표에서 바깥으로 올라가며 Computed 창의
position을 보면div.room·body·html모두static입니다. 기준 상자가 될 조상이 없어 두 꼬리표 모두 처음 화면의 오른쪽 위에서 8px 안쪽에 놓였습니다.
.room에 position: relative를 주면 카드마다 제 기준 상자가 되어, 꼬리표가 저마다 제 카드 테두리 안쪽에서 8px 떨어진 자리에 놓입니다(브라우저 규칙 8). relative는 top 등이 없으니 카드 자리를 옮기지 않습니다.
다르게 고쳐도 되는 곳: position: sticky도 static이 아니라 기준 상자가 되지만, 카드가 굴릴 때 붙는 일까지 함께 맡게 됩니다. 기준 상자만 바라면 relative입니다.
- 흔한 오답은
.room에position: absolute를 주는 것입니다. 기준 상자는 되지만 카드 둘이 흐름에서 빠져 한자리에 겹칩니다. .done의top·right값을 바꿔 보는 것도 흔합니다. 기준이 처음 화면인 채라 두 꼬리표는 여전히 한자리에 겹칩니다.
다시 볼 레슨: 기준 상자와 absolute
문제 12 (만들어 보기)
독서 동아리의 책 카드입니다. '이달의 책' 꼬리표를 표지 왼쪽 위 모서리에서 8px씩 안쪽에 겹치고, 표지에 가리지 않게 하려 합니다. 표지 .cover에는 다른 일(표지 안 쪽수 표시) 때문에 position: relative가 이미 있습니다. 하위 목표 주석만 남긴 틀의 …를 채우세요.
<div class="book">
<span class="pick">
이달의 책
</span>
<div class="cover">
표지
</div>
<p>작은 아씨들</p>
</div>
.book {
width: 200px;
}
.cover {
position: relative;
height: 120px;
background-color: #d2d2d7;
}/* 1. 기준 상자 정하기 */
…
/* 2. 겹칠 상자 빼기 */
…
/* 3. 자리 정하기 */
…
/* 4. 쌓는 차례 */
…
나와야 할 결과는 둘입니다.
- 꼬리표의 위 · 왼쪽 가장자리가 표지 위 · 왼쪽 가장자리에서 8px씩 안쪽이다.
- 꼬리표 가운데 자리에서 맨 위에 그려진 것이 꼬리표다 — 표지에 가리지 않는다.
힌트
하위 목표 넷을 차례로 하나씩 채웁니다. 4는 꼬리표와 표지 가운데 position을 가진 쪽이 몇인지 세어 보고 정합니다.
정답
모범 답입니다.
<div class="book">
<span class="pick">
이달의 책
</span>
<div class="cover">
표지
</div>
<p>작은 아씨들</p>
</div>
.book {
width: 200px;
}
.cover {
position: relative;
height: 120px;
background-color: #d2d2d7;
}/* 1. 기준 상자 정하기 */
.book {
position: relative;
}
/* 2. 겹칠 상자 빼기 */
.pick {
position: absolute;
/* 3. 자리 정하기 */
top: 8px;
left: 8px;
/* 4. 쌓는 차례 */
z-index: 1;
}.cover의 위 자리8px.pick의 위 자리16px.pick의 왼쪽 자리16px.pick의 맨 위 요소span.pick
첫 결과 화면은 앞 CSS만, 둘째 결과 화면은 이어 쓴 CSS까지 그린 것입니다.
- 표지는 카드 맨 위에서 시작하니, 카드
.book을 기준 상자로 두면top: 8px·left: 8px이 곧 표지 모서리에서 8px 안쪽입니다. - 꼬리표와 표지가 둘 다
position을 가져, 그대로면 HTML에서 뒤에 오는 표지가 위에 그려집니다. 꼬리표에z-index: 1을 줘 표지(처음 값auto) 위로 올립니다.
확인한 결과가 둘 다 맞으면 맞습니다. 코드가 모범 답과 달라도 됩니다.
다르게 써도 되는 곳:
z-index는 1보다 큰 수여도 됩니다. 표지가 처음 값auto라 0보다 크면 위로 옵니다.- 3과 4의 선언을 따로
.pick규칙 둘로 나눠 써도 같습니다.
흔한 잘못:
- 4를 비워 두면 꼬리표 자리는 맞아도 표지가 그 위를 덮어 꼬리표가 보이지 않습니다.
<div class="book">
<span class="pick">
이달의 책
</span>
<div class="cover">
표지
</div>
<p>작은 아씨들</p>
</div>
.book {
position: relative;
width: 200px;
}
.cover {
position: relative;
height: 120px;
background-color: #d2d2d7;
}.pick {
position: absolute;
top: 8px;
left: 8px;
}.pick의 맨 위 요소div.cover
- 1을 비워 두면 꼬리표의 기준이 처음 화면이 되어, 표지 모서리가 아니라 페이지 모서리에서 8px 안쪽(위 자리 8px)에 놓입니다. 이 카드는 페이지 맨 위에 있어 거의 같아 보이지만, 카드 위에 다른 글이 오면 꼬리표만 페이지 위에 남습니다.
- 기준 상자
.book에absolute를 주면 카드가 흐름에서 빠져, 아래에 오는 글이 카드 밑으로 올라옵니다. 기준 상자에는relative입니다.
다시 볼 레슨: 기준 상자와 absolute · sticky 머리글과 z-index
문제 13 (만들어 보기)
레시피 노트의 열셋째 단계입니다(⟨컴퓨터⟩ · 25분 안팎 · 걸음마다 멈춰도 됩니다). 목록 페이지 카드마다 배지를 그림 위에 겹치고, 두 페이지의 머리글을 굴려도 창 맨 위에 붙어 있게 합니다. 13단원 연습 문제의 만들어 보기를 마쳤다면 그 폴더에서 이어 갑니다.
이 단계 시작 파일 — 13단원 끝 상태
recipe-note 폴더에 세 파일을 받아 둡니다.
recipe-note 안에 images 폴더를 만들고 그림 여섯을 받아 둡니다. 앞 단계에서 받았으면 그대로 씁니다.
할 일 — 걸음 넷입니다. 이 단계는 style.css만 고칩니다.
걸음 1 — 카드 그림 위 배지. 겹치기 틀의 1 ~ 3을 씁니다. 카드 .recipe-card를 기준 상자로 두고, 카드 안의 배지만 흐름에서 빼, 카드 테두리 안쪽에서 위 24px · 왼쪽 24px에 놓습니다. 카드 안쪽 여백이 16px이라 그림 왼쪽 위 모서리에서 8px 안쪽입니다. 김치볶음밥 페이지의 '한식' 배지는 건드리지 않습니다.
걸음 2 — 붙어 있는 머리글. .site-header를 굴려도 창 맨 위(top: 0)에 붙게 하고, 아래 글이 비쳐 보이지 않게 바탕을 --surface로 칠합니다.
걸음 3 — 쌓는 차례. 목록을 내릴 때 카드가 머리글 아래로 지나가도록 머리글에 z-index: 10을 줍니다.
걸음 4 — 가리지 않는 제목. 김치볶음밥 페이지에서 '조리 순서' 링크로 옮겨 간 제목이 붙은 머리글에 가리지 않게, h2 규칙에 scroll-margin-top: 8rem을 더합니다.
확인 목록:
- 목록 페이지 카드마다 배지가 제 카드 그림의 왼쪽 위 모서리 안쪽에 겹친다 — 배지 여섯이 한곳에 몰리지 않는다(화면 · 걸음 1).
- 김치볶음밥 페이지의 '한식' 배지는 제목 아래 줄 그 자리 그대로다(화면 · 걸음 1).
- 목록을 끝까지 내려도 머리글이 창 맨 위에 붙어 있고, 그 뒤로 카드 글자가 비치지 않는다(화면 · 걸음 2).
- 내릴 때 카드와 배지가 머리글 아래로 지나간다(화면 · 걸음 3).
- 김치볶음밥 페이지에서 '조리 순서'를 누르면 '조리 순서' 제목이 머리글 아래에 다 보인다(화면 · 걸음 4).
- 창 폭을 줄일 수 있는 데까지 줄여도 머리글이 창 맨 위에 붙어 있고 가로 스크롤이 없다(화면 · 네 걸음 끝).
폰으로만 따라왔다면 이 물음 하나로 대신합니다. 걸음 1 · 2만 하고 걸음 3을 빠뜨리면, 목록을 내릴 때 어떻게 보일까요?
- ① 머리글이 붙지 않고 함께 올라간다
- ② 카드가 머리글 위로 지나가 머리글을 가린다
- ③ 걸음 3을 한 것과 같다
힌트
걸음마다 그 걸음의 확인 목록을 봅니다. 걸음 1은 겹치기 틀의 하위 목표 1 · 2 · 3 차례 그대로입니다.
정답
모범 답입니다. 바뀐 곳만 싣습니다 — 다 고친 style.css는 아래 받기 파일과 같습니다(index.html · kimchi.html은 13단원 끝 상태 그대로).
h2 {
font-size: 1.375rem;
scroll-margin-top: 8rem;
}.site-header {
position: sticky;
top: 0;
z-index: 10;
…
background: var(--surface);
}.recipe-card {
position: relative;
…
}
.recipe-card .badge {
position: absolute;
top: 24px;
left: 24px;
}카드 하나와 머리글을 떼어 그린 모습입니다. 받기 파일과 같은 선언만 골랐습니다.
<div class="recipe-card">
<img
src="images/kimchi.svg"
alt=""
width="200"
height="150"
/>
<span class="badge">
한식
</span>
</div>
.recipe-card {
position: relative;
padding: 16px;
border: 1px solid #d2d2d7;
}
.recipe-card img {
display: block;
}
.recipe-card .badge {
position: absolute;
top: 24px;
left: 24px;
}img의 위 자리25px.badge의 위 자리33pximg의 왼쪽 자리25px.badge의 왼쪽 자리33px.badge의 맨 위 요소span.badge
카드 테두리 1px 안쪽에서 24px — 안쪽 여백 16px을 지나 그림 모서리에서 8px 안쪽입니다. 배지는 position이 있어 흐름 안의 그림 위에 그려집니다.
<header class="site-header">
레시피 노트
</header>
<div class="recipe-card">
카드
</div>
.site-header {
position: sticky;
top: 0;
z-index: 10;
background: #ffffff;
}
.recipe-card {
position: relative;
height: 1600px;
}.site-header의 창 위 자리0px.site-header의 맨 위 요소header.site-header
확인 목록을 다 채웠으면 맞습니다. 코드가 모범 답과 달라도 됩니다.
다르게 써도 되는 곳:
- 배지 자리는 그림 안쪽이면 됩니다.
right: 24px로 그림 오른쪽 위에 둔다면 그림이 200px이라 카드가 넓을 때 그림 밖으로 나가니, 왼쪽에 두는 편이 맞습니다. - 머리글
z-index는 1보다 큰 수면 됩니다. 카드가 처음 값auto라서입니다. scroll-margin-top은 머리글 높이보다 크면 됩니다. 글자 크기를 따라가도록 rem으로 적었습니다.
흔한 잘못:
- 배지 규칙을
.badge로만 쓰면 김치볶음밥 페이지의 '한식' 배지도 흐름에서 빠집니다. 그 페이지에는position을 가진 조상이 없어 처음 화면의 위 24px · 왼쪽 24px, 머리글 자리로 날아가 머리글에 가려집니다. 카드 안의 배지만.recipe-card .badge로 고릅니다. - 걸음 3을 빠뜨리면
relative인 카드가 HTML에서 뒤에 와 붙은 머리글 위로 지나갑니다. - 걸음 2에서 바탕을 칠하지 않으면 머리글이 붙어도 뒤로 지나가는 카드 글자가 비쳐 보입니다.
폰 물음의 답은 ②입니다. 걸음 1에서 카드에 준 position: relative 때문에, HTML에서 뒤에 오는 카드가 머리글 위에 그려집니다.
다시 볼 레슨: 기준 상자와 absolute · sticky 머리글과 z-index