웹 프로젝트를 진행할 때 빼놓을 수 없는 것이 position과 display 입니다.
수많은(?) div 태그들의 배치를 도와주며
때로는 가로로, 때로는 세로로, 또는 어떠한 경우엔 요소를 없애기도 합니다.
때론 브라우저 기준으로, 아니면 부모 태그의 기준으로 대상 태그의 위치를 잡아줄 수 있는 position입니다.
1. static 2. fixed 3. relative 4. absolute 5. sticky
아무 속성도 정의하지 않았을 때 지정되는 기본 값입니다.
나열된 순서대로 위치합니다.
<p>내가 p태그다</p>
<div>내가 div태그다</div>
<span>안녕!</span><span>안녕!!</span>
예를 들어 위의 예제는 p -> div -> span -> span 순서로 배치됩니다.
위치가 직전에 있는 태그와 관련되므로 top,left,right,bottom 등은 사용할 수 없습니다.
static일 때의 위치를 기준으로 배치하며, top~bottom을 사용할 수 있습니다.
<div id='1' style={{backgroundColor:'yellow'}}>
</div>
<div id='2' style={{backgroundColor:'red', position:'relative'}}>
</div>
id를 기준으로 배치되는 기준을 살펴보면,
2번 div는 static 기준으로 1번 div 옆에 위치하게 됩니다.
만약 이 상태에서
style={{right:'100px'}}
로 오른쪽에서 100px 이동하게끔 만들면
static에서는 할 수 없었던 영역 겹치기가 가능합니다.
<div id='1'>
<div id='2' style={{position:'relative', height:'300px'}}>
</div>
</div>
예를 들어 부모인 1번 태그에 너비, 높이가 설정되어있지 않다고 가정하면
자식 div의 높이인 300px가 부모 태그에 적용됩니다.
그리고 'margin 병합 현상' 이 발생하게 됩니다.
margin 병합 현상
'여백 붕괴 현상' 이라고도 한다.
예를 들어 부모 태그의 margin-top이 10px이고
자식 태그의 margin-top이 20px이면 부모 태그는 20px의 margin-top을 가지게 된다.
참고 링크 : https://webclub.tistory.com/485
눈에 보기 좋은 사진이 있어서 인용했습니다.
상식적으로 생각했을 때 부모는 부모대로, 자식은 부모 태그에 맞춰서
margin이 주어져야되지만 두 margin 값 중 더 큰 값이 부모 바깥 여백에 적용됩니다.
이를 해결하는 것은 내부에 경계선 (예를 들면 hr) 등을 놓아주거나
혹은 부모태그에서 padding을 사용하면 됩니다.
저 같은 경우엔 후술하겠지만,
부모 태그에 relative를 놓고 자식 태그에 absolute를 부여하여
부모 태그 영역 내부에서 입맛대로 배치하는 것을 좋아합니다.
직역하면 '절대적인'이란 뜻이 있는만큼, 어떠한 것에 기준을 두지 않고
미리 설정한 위치에 배치되도록 하는 속성입니다.
독립적인 개체처럼 움직이기에 마진 병합 현상이 없으며
top~bottom 속성 사용이 가능합니다.
전체 영역에서 자유롭게 배치할 수 있는 부분이 있어
3차원 속성이라 부르기도 합니다.
<div id='1' style={{position:'relative',top:'30px'}}>
</div>
<div id='2' style={{position:'absolute',top:'30px'}}>
</div>
1번태그는 브라우저 페이지를 기준삼아 위에서부터 30px만큼 내려갑니다.
2번태그가 relative였다면 1번 태그를 기준으로 30px, 즉 전체 페이지에서 60px 아래로 내려가있겠지만
absolute로 설정되어있어 1번 div 태그와 2번 div태그는 결론적으로 겹친 상태로 표시됩니다.
특정 위치에 '고정된'상태가 됩니다.
흔히 볼 수 있는 메뉴 바들이 fixed 속성을 가지고 있습니다.
margin은 상대적인 속성이므로 적용되지 않으며
top~bottom은 브라우저 기준으로 적용됩니다.
자연스럽게 위치를 지정할 수 있으므로 absolute와 마찬가지로
3차원 속성이라고 불립니다.
메뉴바 뿐만 아니라, 사용자의 입장에서 항상 눈길이 가있어야하는 컨텐츠라거나, 스크롤을 내렸을 때 보이는 top 버튼 등에도 사용됩니다.
sticky는 relative와 fixed의 결합처럼 기능합니다.
특정 범위를 초과하지 않았을 때는 relative로 기능하지만
초과하면 fixed 상태가 됩니다.
예를 들어 top:50px의 sticky상태라면
브라우저의 스크롤을 기준으로 50px를 넘으면 fixed됩니다.
코오롱 몰의 이벤트 세션이 sticky 속성을 사용하고 있습니다.
top:72px로, 72px가 되기 전까지는 사진이 움직이지만
72px가 딱 감지되자마자 고정된 상태로 유지되는 것을 볼 수 있으며
또한 최적화를 위해서인지, div 태그가 겹겹이 쌓아올려질때마다
직전에 있었던 div 태그의 visibility가 hidden으로 설정되는 것을 확인할 수 있었습니다.
<div id='1' style={{marginBottom:'15px'}}>
</div>
<div id='2' style={{marginTop:'30px'}}>
</div>
단방향이었던 부모자식간의 관계와는 다르게
각각 개별 요소끼리 양방향의 margin이 설정되어 있는 경우
겉으로 보기에는 15px+30px를 통해
1번 div, 2번 div는 45px의 간격을 가져야될 것처럼 보이지만
실상 구현해보면 30px로 적용됩니다.
이 부분은 간단히 한쪽의 div에만 간격을 설정하면 되는 일이고
또는 absolute를 사용해 입맛에 맞게 배치하면 됩니다.