포지셔닝의 큰 개념은 일반적인 문서 흐름을 벗어나 흥미로운 효과를 낼 수 있도록 만들어준다. 예를 들면, 박스의 위치를 보통 흐름
에서 벗어나 위치를 약간 변경한다거나, 박스 위에 박스를 겹치게 한다거나, 스크롤 해도 항상 브라우저 창 동일한 위치에 놓이게 하고 싶다든지.. 그런 당신을 위해 준비했습니다! 포지셔닝~~
정적 포지셔닝은 모든 요소에 주어지는 기본값이다. 즉, 요소들이 보통 흐름
으로 문서에 배치된 다는 것이다.
.positioned {
position: static;
background: yellow;
}
예제를 통해 두 번째 단락의 배경 색깔이 노란 색으로 바뀐 것을 제외하고는 다른 차이가 없다는 것을 확인할 수 있다.
상대 포지셔닝은 정적 포지셔닝과 매우 유사하나, 다른 점은 자신의 현재 위치를 기준으로 위치를 이동시킬 수 있다.
position: relative;
상대 포지셔닝으로 설정하고 살펴보면 무언가 바뀐게 없다. 그럼 요소의 위치를 어떻게 수정할까? top
, bottom
, left
, right
를 이용하면 된다.
top
, bottom
, left
, right
는 position
과 함께 사용되어 기준 위치에 비례해 요소의 위치를 옮겨버린다.
top: 30px;
left: 30px;
오 뭔가 이동하긴 했는데, 혹시 이상하다고 생각했나? 아마 "너는 위로 30px만큼 이동하고, 왼쪽으로 30px 이동해라"고 명령했을지도 모른다. 그런데 실제로 예제를 보면 그 반대로 이동했다. 왜그럴까? 그렇게 만들어졌기 때문에 그냥 외우면 된다 ㅋㅋㅋ.. "~쪽으로 이동해라~" 보다는 "~쪽에서 밀어라" 로 생각하는게 더 편하다.
절대 포지셔닝은 아주아주 다른 결과를 가져온다. 한번 적용해보자.
position: absolute;
요소가 절대 포지셔닝을 가지는 순간 다른 모든 요소들과는 별개로 독자적으로 변한다. 즉, 페이지의 다른 요소의 위치와 간섭하지 않게 된다.
그리고 top
, bottom
, left
, right
의 기준 위치가 변한다. 상대 포지셔닝에서는 자기 자신의 위치를 기준으로 변했지만, 절대 포지셔닝에서는 자기 부모의 요소의 위치를 기준으로 변한다.
절대 포지셔닝에서 중요한 점은 위에서 말했듯이 자기 부모를 기준으로 움직인다는 점이다. 부모 요소가 위치 속성을 가지고 있지 않으면 초깃값으로 모든 조상 요소에 정적 위치가 부여된다. 그런데, 만약 부모 요소 중 상대 포지셔닝을 가지고 있는 부모가 있다면 그 부모를 기준으로 절대 포지셔닝을 가진 자식이 움직인다.
position: relative;
위 예제에서 positioned
이라는 클래스를 가진 p 태그는 절대 포지셔닝
을 가지고 있는데, 그의 부모인 body 태그가 상대 포지셔닝
을 가지고 있으므로 body 태그를 기준으로 p 태그는 움직일 것이다.
포지셔닝을 다루다 보면 요소들이 겹치기 시작한다. 우리가 위에서 본 예제에서, 절대 포지셔닝을 지정해준 요소가 다른 요소들보다 상위에 나타난다. 왜냐하면 포지셔닝 요소가 비포지셔닝 요소보다 우위를 점하기 때문이다.
그렇다면, 포지셔닝을 가진 요소가 여러 개라면?
그렇다면 순서를 변경할 수 있나? z-index
속성을 사용하면 가능하다! z-index는 z축을 가리킨다.
웹 페이지에는 x축, y축 외에도 z축이 있다. z축을 설정함으로써, 어느 요소를 더 위에 둘지 결정할 수 있다. 값이 커질 수록 요소를 더 위에 두고, 반대로 작아지면 아래에 둔다. 모든 요소는 z-index
값이 기본적으로 0이다.
고정 포지셔닝은 절대 포지셔닝과 같은 방식으로 작동한다. 단, 한 가지 중요한 차이점이 있다. 절대 포지셔닝은 <html>
요소나 가까운 부모 요소를 기준으로 비례해 요소를 고정시키지만, 고정 포지셔닝은 브라우저 뷰 포트 자체를 기준으로 비례해 요소를 고정한다. 즉, 잘 활용하면 제자리에 고정된 메뉴바 같은 것을 만들 수 있다.
웹페이지를 스크롤 할 수 있게 body
태그에 height
값을 부여해주고, <h1>
요소에 position: fixed;
를 부여했다.
body {
width: 500px;
height: 1400px;
margin: 0 auto;
}
h1 {
position: fixed;
top: 0;
width: 500px;
margin: 0 auto;
background: white;
padding: 10px;
}
이제 예제를 보면, 스크롤 막대를 밑으로 내려도 <h1>
태그가 움직이지 않고 고정돼 있는 모습을 볼 수 있다.
문제가 하나 있다. 박스 요소 하나가 시작부터 제목 밑에 깔려 있다. 그 이유는 포지셔닝을 가지고 있는 요소가 포지셔닝이 없는 요소보다 위에 있기 때문에 가려져서 안보이는 것이다. 그래서 첫 번째 단락의 margin-top
을 조금 수정해서 내용을 아래로 끌고 왔다.
p:nth-of-type(1) {
margin-top: 60px;
}
position: sticky
라고 불리는 또 다른 포지셔닝 값이 있다. 이 포지셔닝은 조금 특별하다. 상대 포지셔닝과 고정 포지셔닝을 합친 느낌이라고 보면 된다. 요소가 어느 특정값까지 스크롤 되기 전까지는 상대 포지셔닝처럼 행동하다가 그 뒤에는 위치가 고정된다.
예제같은 경우는 top: 30px
만큼 요소가 스크롤 되었을 때 페이지 상단에 착 달라붙는 모습을 볼 수 있다.