html element의 위치를 지정해줘야 하는 경우가 많다.
예를 들어 nav-bar는 사용자가 스크롤을 내려도 늘 화면의 상단 위에 있어야 한다. 이미지 위에 텍스트를 얹어야 하는 경우도 있다.
이런 작업은 position 속성으로 구현할 수 있다.
우선 document flow에 관해 간단하게 알아보자.
'html이 일반적으로 렌더링되는 방식'이라고 생각하면 된다.
즉, 블록 요소는 한 줄에 하나씩만 렌더링 되고, 인라인 요소는 같은 줄에 여러 개가 렌더링 된다. 또한 모든 요소는 위에서부터 아래로 차례에 맞게 렌더링 된다.
마치 아래 그림처럼 말이다. "Float me"라는 요소가 위에 있고, 그 아래에 텍스트 요소가 위치한다.
하지만 document flow가 수정되면 마치 지저분한 책상처럼 요소들이 따로 논다. 아래 그림을 보면 이해가 될 것이다. (위에서 아래대로 차례에 맞게 렌더링 되지 않고 제멋대로 나열된 것처럼 보인다.)
document flow를 수정할 수 있는 방법은 두 가지가 있다.
이중 position에 대해 알아보자.
position 속성을 부여함으로써 html 요소의 위치를 정할 수 있다.
크게 2가지가 중요하다.
positioning context
)position 속성에 부여할 수 있는 5가지 값을 하나씩 알아보자.
기본값이다. 따라서 position을 명시하지 않은 html 요소는 static이다.
이 상태에서는 top, bottom, left, right, z-index를 설정해봤자 아무 일도 일어나지 않는다.
document flow에서 이탈하게 된다.
positioning context
은 viewport가 된다.
즉 위치 기준점은 브라우저가 된다는 뜻이다. 예를 들어 top: 100px
이라고 설정하면 브라우저 상단에서 100px 떨어진 곳에 나타나게 되며 스크롤을 내려도 늘 같은 위치에 고정되어 있다.
document flow에서 이탈하게 된다.
positioning context
은 position 속성을 명시한 가장 가까운 조상 element가 된다. 어떠한 조상도 position 속성을 명시하지 않았다면 html이 기준점이 된다.
빨간 박스는 position: absolute
에 bottom: 0; right: 32px
로 설정했다. 부모인 파란 박스가 position: relative
로 설정되어 있으므로 빨간 박스는 파란박스의 바닥에서 0, 우측에서 32px만큼 떨어진 곳에 위치하게 된다.
document flow을 따른다.
positioning context
은 자기자신이다.
아래 그림의 초록 박스는 position: relative; left: 30px
로 설정되어 있다. 따라서 원래 있던 자리에서 30px만큼 이동해 있다.
relative와 fixed를 섞어놓은 것처럼 작동한다.
스크롤 위치가 지정해놓은 곳에 도달하기 전까지는 relative처럼 작동하고, 도달 후에는 fixed처럼 작동한다.
아래처럼 설정해놓으면 div.sticky가 top: 0이 되기까지는 relative처럼 움직이다가 그 이후로는 fixed처럼 움직인다. (링크를 눌러서 직접 스크롤링을 해보면 바로 이해하게 될 것이다. https://www.w3schools.com/css/tryit.asp?filename=trycss_position_sticky)
div.sticky {
position: sticky;
top: 0;
padding: 5px;
}
z축을 기준으로 어떤 요소를 위에, 어떤 요소를 아래에 놓을지 정하는 기준이다. 기본값은 auto, 즉 0이다.
position이 부여되야 사용 가능하다.
z-index가 높다고 무조건 사용자쪽에 놓이는 것이 아니다. stacking context를 고려해야 한다.
자식 요소의 z-index보다 부모 요소의 z-index가 우선한다.
div 1, 2, 3은 형제이고 div 4, 5, 6은 div3의 자식이다.
따라서 z-index의 값대로 div1 > div3 > div2가 되며, div4의 z-index가 div1의 그것보다 높다고 해서 더 위에 놓이지 않는 것이다.
자식 element의 position 설정을 통해 부모 element 밖으로 빠져나갈 수 있다.
이를 방지하는 설정이 부모 element에 overflow: hidden
이다.
하지만 특이하게도 body에 overflow: hidden
이라고 해봤자 아무 효과가 나타나지 않는 경우가 있다.
이런 경우에는 html에 overflow: hidden
혹은 overflow: auto
설정을 부여하면 된다.