본문 바로가기

Programming

[CSS] Position의 모든것★

이번 포스팅에서는 웹페이지에서 요소의 위치를 자유자재로 정렬하기 위한 모든 개념을 꼼꼼히 정리해볼 것이다.

 

1. Position

 

CSS에서 Position은 요소가 문서 상의 어디에 위치할 것인가를 지정한다.

최종적으로 left, right, top, bottom (오프셋) 속성으로 문서의 최종 위치를 정의하게 되는데 

Position의 값에 따라 그 위치를 지정하는 방식을 결정하게 된다.

 

 

static(기본값) 기본값. 오프셋 속성을 무시한다.
relative
absolute 가장 가까운 부모요소의 위치에 따라 상대적으로 배치
(가까운 부모요소가 없다면 가장 상위 컨테이너에 따라 배치)

fixed 문서의 최상위 컨테이너를 기준으로 배치
(단, 부모요소 중 transform, perspective, filter 속성 중 하나라도 none이 아니라면 해당 부모요소를 기준으로 배치)
sticky   끈끈한 요소 가장 가까운 스크롤 되는 부모요소와 표 관련 요소를 포함한 블록 레벨의 부모요소를 기준으로 배치

 

 

간단하게 정의를 알아봤다. 그렇다면 어떻게 써먹을 수 있을까?

 

 

 

우선 static은 이름부터가 '정적인'이라는 의미로 top, left등의 위치 속성을 무시하고 기본적으로 배치되는 위치에서 움직이지 않는다.

 = 항상 페이지의 기본적인 흐름에 따라 배치된다.

 

 

그래서 위치를 지정해야 하는 경우에는 잘 사용되지 않지만 앞에서 지정해 둔 위치 속성을 무시하고싶은 경우 사용될 수 있다.

<!DOCTYPE html>
<html>
	<head>
    	<style>
            span {
            	position: static;
                top:50px;
                border: 5px solid green;
            }
            div {
            	position: static;
                left:30px;
                border:5px solid red;
                margin: 10px;
                }
        </style>
    </head>
    <body>
        <span>span</span>
        <span>span은 요소의 너비만큼만 자리를 차지하지</span>
        <div>div</div>
        <div>div는 전체 너비를 차지하지</div>
    </body>
</html>

 

요쇼의 top, left값을 지정하였으나 위치는 변하지 않았다.

 

 

위처럼 너비 차지에 차이가 나는 이유는 span은 인라인태그, div는 블록태그이기 때문이다. 

* inline과 block태그의 특징과 차이점

- top, left, right, bottom 등의 오프셋 속성을 추가해도 요소의 위치는 바뀌지 않는다.

 

relative는'상대적'인 위치 지정 방식이라고 할 수 있고, static인 상태에서 지정되어있던 기본적인 위치를 기준으로 움직인다.

 

 

자기 자신의 원래 위치에 대하여 상대적으로 배치된다고 할 수 있다.

<!DOCTYPE html>
<html>
	<head>
    	<style>
            span {
            	position: relative;
                left:50px;
                bottom:50px;
                border: 5px solid green;
            }
            div {
            	position: relative;
                bottom:30px;
                border:5px solid red;
                margin: 10px;
                }
        </style>
    </head>
    <body>
        <span>span</span>
        <span>span은 요소의 너비만큼만 자리를 차지하지</span>
        <div>div</div>
        <div>div는 전체 너비를 차지하지</div>
    </body>
</html>

 

span은 원래 위치에서 50px오른쪽으로 이동, div는 30px아래로 이동했다.

 

그런데 조금 이상한 점이 있다.

 

초록색의 경계선으로 표시된 span태그에는 left값, 즉 왼쪽값을 50px이라고 설정했는데 왜 오른쪽으로 이동했을까?

 

left:50px이라는 코드를 작성하면서 내가 의도했던 바는 사실 '왼쪽으로 50px 이동해라!'라는 것이었다. 

 

그런데 결과 사진에 나와있듯이 span 태그는 기존의 위치에서 오른쪽으로 50px 이동했다.

 

내가 JS를 만든 사람이 아니기에 왜라는 물음에는 답하기가 힘들지만 배우는 입장에서 쉽게 생각해보자면

'왼쪽을 기준으로 50px만큼 떨어져라(50px만큼 여백을 부여해라)' 라는 것이다.

margin(내부여백)속성을 사용할 때와 동일하게 생각하면 될 것 같다.

 

 

그리고 span태그의 left를 50px, bottom를 50px로 지정했는데 오른쪽으로 50px만큼 이동했지만 위쪽으로 50px만큼은 이동하지 않았다. 

이것은 span태그가 inline 태그라서 발생한 문제이다. 위쪽에 있는 'inline과 block태그의 특징과 차이점' 참고!

 

absolute는 '절대적'인 위치 지정 방식으로 가장 가까운 곳에 위치한 모요소를 기준으로 움직인다.

단, absolute로 포지셔닝 된 자식요소의 부모요소가 될 수 있는 조건은 relative 또는 absolute로 포지셔닝이 되어 위치가 지정되어있는 요소여야한다. 

 

즉 포지션의 속성을 absolute로 지정해 요소의 위치를 지정하려면 부모요소의 포지션 속성을 relative 또는 absolute로 지정해야 하고 그렇지 않으면 최상위 컨테이너로 부모가 지정된다.

<!DOCTYPE html>
<html>
    <head>
        <style>
            body{
                background:wheat;
            }
            div {
                margin: 30px;
                }
            #parent {
                background:skyblue;
                padding:30px;
                width:200px;
                height:350px;
            }
            #parent div{
                width:50px;
                height:50px;
                background:yellow;
                padding:30px;
            }
        </style>
    </head>
    <body>
        <div id="parent">
            parent
            <div id="first-child">
                first-child
            </div>
            <div id="second-child">
                second-child
            </div>
        </div>
    </body>
</html>

 

body는 오트밀색, parent는 하늘색, child는 노란색으로 지정했다.

 

↑ 현재 세 요소 모두 포지션이 static인 기본 상태

 

 

1) 자식태그만 absolute로 변경, 각각 right: 20px;, bottom:20px;

 

 

오잉? 예상 밖의 결과가 나왔다.

 

 

일단 예상대로 자식요소들은 body영역을 중심으로 배치되었다. 

그런데 왜 블록요소였던 자식 div가 인라인 요소가 된 듯이 전체너비를 차지하고있지 않은가이다.

그 이유는 position의 값을 absolute로 준 순간 해당 요소들은 더이상 문서의 기본적인 흐름을 따르지 않기 때문이다.(out of page flow)

 

그 요소들은 자동적으로 display:inline;으로 지정한 듯하게 배치된다.

(이때 display:block이나 display:inline-block;으로 지정한다 해도 마찬가지다.)

 

그래서 각각의 요소에 적절한 width와 height값을 지정해주었다.

 

 

body는 오트밀색, parent는 하늘색, child는 노란색으로 지정했다.

 

다시 각각 right: 20px;, bottom:20px; 지정

 

 

예상대로 body태그를 중심으로 배치된 모습이다.

2) 부모태그를 relative로 변경

 

 

이제는 부모태그를 기준으로 배치된 모습이다.

3) 부모태그를 absolute로 변경

 

 

궁금해서 해봤는데 뭔가 미세~하게 달라진 느낌이다. 기분탓인지도 모르겠을정도로 미세한 변화가 있는 것 같긴 한데 정확히 어떤 차이가 있는지는 잘 모르겠다...

// TODO : 자식요소가 absolute일 때 부모요소가 absolute인 경우와 relative인 경우가 어떤 차이가 있는지 알아보기☆

나는 자식 요소의 위치만을 고려해 부모의 요소가 relative일 때, 또는 absolute일 때 자식 요소의 위치에 변화가 생긴다고 생각했다.

그러나 child의 부모인 parent요소도 body 요소의 자식 요소이다.

그렇다면 child의 위치에 변화가 생긴 것이 아니라 parent요소가 그 부모(body)요소를 기준으로 위치에 변화가 생긴 것이라고 볼 수 있다.

fixed는 '고정된' 위치 지정 방식으로 웹 페이지를 기준으로 위치가 지정된다. 스크롤 시에도 고정되어있다.

 

fixed를 사용하는 경우는 사이트 상단의 로고나 메뉴 등의 보통 header로 지정되는 영역을 스크롤과 관계없이 고정하고 싶을 때 사용한다. 

말은 어렵지만 직접 보면 확 와닿을 것이다.

ex) 넷플릭스

 

스크롤을 내려도 상단의 로고+메뉴영역은 고정되어있다.