📌 참고 사이트
position - CSS: Cascading Style Sheets | MDN (mozilla.org)
position - CSS: Cascading Style Sheets | MDN
CSS position 속성은 문서 상에 요소를 배치하는 방법을 지정합니다. top (en-US), right (en-US), bottom (en-US), left (en-US) 속성이 요소를 배치할 최종 위치를 결정합니다.
developer.mozilla.org
컨테이닝 블록의 모든 것 - CSS: Cascading Style Sheets | MDN (mozilla.org)
컨테이닝 블록의 모든 것 - CSS: Cascading Style Sheets | MDN
요소의 크기와 위치는 컨테이닝 블록(containing block)의 영향을 받곤 합니다. 대부분의 경우, 어떤 요소의 컨테이닝 블록은 가장 가까운 블록 레벨 조상의 콘텐츠 영역이나, 항상 그런 것은 아닙니
developer.mozilla.org
[HTML/CSS] Position sticky 적용 방법 | Deeplify
[HTML/CSS] Position sticky 적용 방법
CSS의 Postion 속성 중 sticky에 대한 소개와 적용 방법을 알아보도록 하겠습니다.
deeplify.dev
📋 position 속성
📍 position: static
➡️ 기본값으로, 요소를 일반적인 문서 흐름에 따라 배치한다.
➡️ top, left, right, bottom, z-index 등의 요소를 이동시킬 수 있는 속성들이 적용되지 않는다.
ex)
다음과 같은 상태를 static으로 하고 이 예시를 활용해 아래에서 계속 이어나가겠다.
💻 HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<link rel="stylesheet" href="index3.css" />
</head>
<body>
<div class="pink">나는 분홍 박스야!</div>
<div class="green">나는 초록 박스야!</div>
</body>
</html>
💻 CSS
.pink {
width: 100px;
height: 100px;
background-color: pink;
float: left;
margin: 0 30px;
}
.green {
position: static; /* 생략 가능 */
width: 100px;
height: 100px;
background-color: green;
float: left;
}
📍 position: relative
➡️ 요소를 일반적인 문서 흐름에 따라 배치하고, 자기 자신을 기준으로 설정한 top, right, bottom, left 값을 기준으로 요소를 움직이는 것이 가능하다.
➡️ position: relative 상태에서 top, right, bottom, left를 적용하면 각각 원래 자기 자신의 위치에서 위로부터, 오른쪽으로부터, 아래로부터, 왼쪽으로부터 얼마만큼 떨어지게 할지를 정할 수 있다.
* top, right, bottom, left를 통해 이루어진 오프셋은 다른 요소에 영향을 미치지 않는다. 즉, 해당 요소가 차지하는 공간은 static일 때와 동일하다. 요소의 위치만 변화시키는 것이다.
➡️ z-index의 값이 auto(z-index가 적용되지 않음)가 아닐 경우, 새로운 쌓임 맥락을 형성한다.
relative 사용 ex)
static에서의 CSS에서 .green의 position을 relative로 바꾸고 top, left를 50px씩 설정해 주자.
.green {
position: relative; /* 주목! */
top: 50px; /* 주목! */
left: 50px; /* 주목! */
width: 100px;
height: 100px;
background-color: green;
float: left;
}
원래 초록 박스의 위치에서 위, 왼쪽으로부터 50px씩 떨어져서 배치된 결과를 볼 수 있다.
z-index 사용으로 쌓임 맥락 형성 확인하기)
CSS를 다음과 같이 변경해 보자.
.pink {
width: 100px;
height: 100px;
background-color: pink;
float: left;
margin: 0 30px;
position: relative; /* 주목! */
z-index: 2; /* 주목! */
}
.green {
position: relative; /* 주목! */
top: 50px; /* 주목 */
right: 50px; /* 주목 */
width: 100px;
height: 100px;
background-color: green;
float: left;
z-index: 1; /* 주목! */
}
두 박스 모두에 position: relative를 적용해 주었고, 초록 박스의 z-index 값을 분홍 박스의 z-index 값보다 더 작게 설정해 주어 분홍색 박스가 초록색 박스를 덮을 수 있게 설정해 주었다.
결과는 다음과 같다.
📍 position: absolute
➡️ 요소가 일반적인 문서 흐름에서 제거된다. 대신 가장 가까운 위치가 지정된(position 속성이 지정된) 조상 요소에 대해 상대적으로 배치된다.
만약 조상 요소들 중 position이 지정된 요소가 없다면 초기 컨테이닝 블록을 기준으로 한다.
❓컨테이닝 블록 식별하기
요소의 크기와 위치는 컨테이닝 블록의 영향을 자주 받는다.
백분율 값을 사용(px가 아닌 %를 사용)한 width, height, padding, margin 속성의 값과 절대적 위치(position이 absolute나 fixed 등일 때)로 설정된 요소의 오프셋 속성값(top, right, bottom, left의 값)은 자신의 컨테이닝 블록으로부터 계산된다.
1️⃣ position 속성이 static, relative, sticky 중 하나이면 컨테이닝 블록은 가장 가까운 조상 블록 컨테이너(inline-block, block 등), 또는 가장 가까우면서 서식 맥락을 형성하는 조상 요소(table, flex, grid, 또는 블록 컨테이너 자기 자신)의 콘텐츠 영역 경계를 따라 형성된다.
2️⃣ position 속성이 absolute인 경우 컨테이닝 블록은 position 속성 값이 static이 아닌 (fixed, absolute, relative, sticky) 가장 가까운 조상의 내부 여백(padding) 영역이다.
3️⃣ position 속성이 fixed인 경우, 컨테이닝 블록은 뷰포트나 페이지 영역이다.
*뷰포트(viewport): 현재 화면에 보여지고 있는 다각형(직사각형)의 영역으로, 뷰포트 바깥의 콘텐츠는 스크롤 하기 전에는 보이지 않는다.
4️⃣ position 속성이 absolute나 fixed인 경우, 다음 조건을 만족하는 가장 가까운 조상의 내부 여백 영역(padding)이 컨테이닝 블록이 될 수도 있다.
1. transform이나 perspective 속성이 none이 아니다.
2. will-change 속성이 transform이나 perspective이다.
3. filter 속성이 none이다.
4. contain 속성이 paint이다.
➡️ 역시 최종 위치는 top, right, bottom, left 값이 지정한다.
➡️ relative때와 마찬가지로 z-index의 값이 auto가 아니라면 새로운 쌓임 맥락을 생성한다.
absolute 사용 ex)
static에서의 CSS에서 .green의 position을 absolute로 바꾸어 보자.
(* float과 absolute는 양립이 불가하므로 position: absolute를 적용하면 float이 적용되지 않게 된다.)
position: absolute가 적용되지 않은 상태라면 분홍 박스 옆에 초록 박스가 위치해야 하지만 초록 박스에 absolute를 적용한 결과 초록 박스가 일반적인 문서 흐름에서 벗어나 가장 왼쪽 위에 배치된 것을 볼 수 있다.
위에서 position 속성이 absolute인 경우 컨테이닝 블록은 position 속성 값이 static이 아닌 가장 가까운 조상의 내부 여백 영역이 컨테이닝 블록이라고 하였는데, 그러한 조상이 없으므로 초기 컨테이닝 블록(웹 페이지의 루트 요소)인 <html>이 기준이 된다.
다음과 같이 top, right 속성을 적용하여 초록 박스를 오른쪽 위에서 오른쪽 아래쪽으로 이동시키기가 가능하다.
.green {
position: absolute;
top: 200px;
left: 200px;
width: 100px;
height: 100px;
background-color: green;
float: left;
}
분홍 박스를 초록 박스의 부모로 만들고, 분홍 박스에 static이 아닌 position을 부여한 경우도 살펴보자.
💻 HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<link rel="stylesheet" href="index3.css" />
</head>
<body>
<!--주목-->
<div class="pink">
나는 분홍 박스야!
<div class="green">나는 초록 박스야!</div>
</div>
</body>
</html>
💻 CSS
.pink {
position: relative; /* 주목 */
width: 100px;
height: 100px;
background-color: pink;
float: left;
margin: 0 30px;
}
.green {
position: absolute;
/* top: 200px; */
/* right: 200px; */
width: 100px;
height: 100px;
background-color: green;
float: left;
}
position만 적용한 초기 상태는 아래와 같이 초록 박스가 분홍 박스의 자식이므로 분홍 박스 텍스트 바로 아래에 겹쳐서 존재한다.
초록 박스에 top과 right를 적용하게 되면 아까처럼 <html>를 기준으로 위치가 조정되는 것이 아니라 position이 지정된 분홍 박스를 기준으로 위치가 이동되게 된다.
따라서 아까의 경우보다 조금 더 오른쪽 아래에 위치하게 된다.
📍 position: fixed
➡️ 요소를 일반적인 문서 흐름에서 제거한다. 대신 뷰포트의 초기 컨테이닝 블록을 기준으로 삼아 배치한다.
➡️ 역시 최종 위치는 top, right, bottom, left 값이 지정한다.
➡️ fixed를 사용하면 항상 새로운 쌓임 맥락을 형성한다. fixed를 적용한 요소는 모든 페이지의 같은 위치에 출력한다. 즉, 스크롤을 내려도 계속 같은 위치에 고정되어 따라 내려온다.
* 처음에 position: fixed만 설정하면 요소가 화면에 보이지 않을 수 있다. 이때 top: 0px를 설정하면 왼쪽 가장 위에 요소가 나타나는 것을 볼 수 있다.
fixed 사용 ex)
💻 HTML
<html>
<head>
<link rel="stylesheet" href="index4.css" />
</head>
<body>
<div class="box">box</div>
<div class="box">box</div>
<div class="box">box</div>
<div class="fixed">I'm fixed!</div>
</body>
</html>
💻 CSS
.box {
width: 100px;
height: 300px;
background-color: violet;
margin-bottom: 20px;
}
.fixed {
top: 0px;
left: 20%;
position: fixed;
font-size: 20px;
background-color: green;
}
* 위 예시에서 top을 0이 아닌 양수 값으로 설정하면 맨 위에 붙지 않고 정해준 만큼 위로부터 떨어진 상태로 고정되게 된다. 즉, top, right, left, bottom을 정해준 것에 따라 고정되는 좌표가 정해지고, 스크롤을 내려도 뷰포트의 그 정해진 좌표 위치에 그대로 고정되어 내려가게 되는 것이다.
📍 position: sticky
➡️ 요소를 일반적인 문서 흐름에 따라 배치한다.
➡️ static과 fixed의 성질을 모두 가지고 있다고 보면 된다. top, right, bottom, left로 설정한 위치(좌표)에 도달하기 전까지는 static, 도달 이후에는 fixed처럼 작동한다.(뷰포트에서 내가 설정한 좌표에 붙어서 따라 내려가게 된다.)
➡️ sticky가 적용된 요소는 부모를 필수적으로 가지고 있어야 제대로 된 결과를 볼 수 있다.
➡️ 항상 새로운 쌓임 맥락을 생성한다.
sticky 사용 ex)
💻 HTML
<html>
<head>
<link rel="stylesheet" href="index4.css" />
</head>
<body>
<div class="box">
box
<div class="sticky">I'm sticky!</div>
</div>
<div class="blank">blank</div>
</body>
</html>
💻 CSS
.box {
margin-top: 200px;
width: 100px;
height: 300px;
background-color: violet;
margin-bottom: 20px;
}
.sticky {
width: 100%;
top: 50px;
position: sticky;
font-size: 20px;
background-color: green;
}
.blank {
width: 100px;
height: 2000px;
background-color: antiquewhite;
}
위 영상을 보면 뷰포트가 I'm sticky!와 y축으로 50px로 떨어진 곳에 닿기 전까지는 I'm sticky!가 static처럼 동작하다가 닿는 순간 I'm sticky!가 계속 뷰포트에서 y축으로 50px 떨어진 상태로 fixed되게 된다.
이것은 부모 요소인 분홍 박스가 뷰포트에서 보이지 않을 때까지 이어진다. 부모 요소가 끝나는 지점에서 I'm sticky가 fixed처럼 동작하는 것이 멈추게 된다.
(top을 0으로 설정할 시 I'm sticky!가 뷰포트에 닿는 순간 뷰포트 상단에 딱 붙어서 부모 요소가 끝날 때까지 fix되게 된다.)
'HTML & CSS' 카테고리의 다른 글
[CSS] flex (0) | 2023.08.10 |
---|---|
[CSS] 마진 상쇄 현상 (0) | 2023.08.10 |
[CSS] display (block, inline, inline-block, none) (0) | 2023.08.09 |
[CSS] float와 clear (0) | 2023.08.08 |
[CSS] Box Sizing (0) | 2023.08.07 |
댓글