[CSS 속성] 레이아웃 (position, z-index)
목차
1. position
2. z-index
position과 offset
요소의 위치를 지정하는 속성이다.
기본값은 static이며 이 값은 offset 값이 적용되지 않는다.
absolute는 부모 요소의 위치를 기준으로 offset 값이 적용된다. 정상 흐름에서 벗어나며 부모의 position값이 static일 경우 조상의 position값이 static이 아닐 때까지 거슬러 올라가 offset의 기준으로 삼는다. 즉, 부모나 조상의 position이 static인 경우 사용하지 못한다.
fixed는 뷰포트(브라우저의 창)를 기준으로 offset 값이 적용된다. 화면 스크롤에 관계없이 항상 화면의 정해진 위치에 위치하게 된다. 부모의 position 속성에 영향을 받지 않는다.
relative는 자기 자신을 기준으로 offset 값이 적용된다. 부모의 position 속성에 영향을 받지 않는다. 정상 흐름을 따르며 주변 요소에 영향을 주지 않는다.
예제를 통해 자세하게 알아보자.
offset을 지정하지 않은 상태와 offset을 지정한 상태를 나눠서 확인해 볼것이다.
<!--offset 지정하지 않음-->
<!--position: static-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<h2>static</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child static">static</div>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
/*position.css 파일*/
.sibling {
padding: 5px;
background-color: gray;
text-align: center;
}
.parent {
border: 1px dashed black;
padding: 10px;
}
.child {
width: 60px;
height: 60px;
padding: 20px;
background-color: #dc3636;
text-align: center;
color: #fff;
font-weight: bold;
border: 1px solid #333;
}
.static {
position: static;
}
static은 position을 따로 설정하지 않았을 때와 동작이 동일하다.
<!--offset 지정하지 않음-->
<!--position: relative-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child relative">static</div>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
/*position.css 파일*/
.sibling {
padding: 5px;
background-color: gray;
text-align: center;
}
.parent {
border: 1px dashed black;
padding: 10px;
}
.child {
width: 60px;
height: 60px;
padding: 20px;
background-color: #dc3636;
text-align: center;
color: #fff;
font-weight: bold;
border: 1px solid #333;
}
.relative {
position: relative;
}
relative의 경우 offset을 지정해주지 않았을 때 브라우저에서는 static과 같아 보인다.
offset을 지정해주면 차이를 확인할 수 있다.
<!--offset 지정하지 않음-->
<!--position: absolute;-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<h2>absolute</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child absolute">absolute</span>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
/*position.css 파일*/
.sibling {
padding: 5px;
background-color: gray;
text-align: center;
}
.parent {
border: 1px dashed black;
padding: 10px;
}
.child {
width: 60px;
height: 60px;
padding: 20px;
background-color: #dc3636;
text-align: center;
color: #fff;
font-weight: bold;
border: 1px solid #333;
}
.absolute {
position: absolute;
}
absolute는 형제 요소들이 absolute 요소를 무시하고 붙은 것을 볼 수 있다.
static을 제외한 대부분의 postion 속성값들은 offset을 적용해야 제대로된 결과를 확인할 수 있다.
absolute는 중요한 성질이 있는데 지금 이 예제에서 absolute는 span 태그로 인라인 레벨 요소이다.
하지만 width와 height가 적용된 것을 볼 수 있다.
position을 absolute로 설정하게 되면 display 값을 block으로 변경한다.
<!--offset 지정하지 않음-->
<!--position: fixed;-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<h2>fixed</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child fixed">fixed</span>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
/*position.css 파일*/
.sibling {
padding: 5px;
background-color: gray;
text-align: center;
}
.parent {
border: 1px dashed black;
padding: 10px;
}
.child {
width: 60px;
height: 60px;
padding: 20px;
background-color: #dc3636;
text-align: center;
color: #fff;
font-weight: bold;
border: 1px solid #333;
}
.fixed {
position: fixed;
}
fixed도 absolute와 동일한 화면인 것을 볼 수 있다.
마찬가지로 offset을 지정하지 않으면 어떻게 동작하는지 확인하기 힘들다.
이번에는 모든 요소에 position과 offset을 지정해서 차이를 확인해보자.
<!--offset 지정-->
<!--position: static;-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<h2>static</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child_offset static" style="top: 40px; left: 40px">static <br>top: 40, left: 40</br></div>
<div class="sibling">sibling 2</div>
</div>
<h2>relative</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child relative">relative</div>
<div class="sibling">sibling 2</div>
</div>
<h2>absolute</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child absolute">absolute</span>
<div class="sibling">sibling 2</div>
</div>
<h2>fixed</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child fixed">fixed</span>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
/*position.css 파일*/
.sibling {
padding: 5px;
background-color: gray;
text-align: center;
}
.parent {
border: 1px dashed black;
padding: 10px;
}
.child, .child_offset {
width: 60px;
height: 60px;
padding: 20px;
background-color: #dc3636;
text-align: center;
color: #fff;
font-weight: bold;
border: 1px solid #333;
}
.child_offset {
background-color: #3677dc;
}
.static {
position: static;
}
.relative {
position: relative;
}
.absolute {
position: absolute;
}
.fixed {
position: fixed;
}
static의 경우 offset 값을 입력해도 그 값을 적용하지 않는다.
<!--offset 적용->
<!--position: relative;-->
<!--css 파일은 위 예제와 동일-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<h2>static</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child_offset static" style="top: 40px; left: 40px">static <br>top: 40, left: 40</br></div>
<div class="sibling">sibling 2</div>
</div>
<h2>relative</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child_offset relative" style="top: 40px; left: 40px">relative <br>top: 40, left: 40</br></div>
<div class="sibling">sibling 2</div>
</div>
<h2>absolute</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child absolute">absolute</span>
<div class="sibling">sibling 2</div>
</div>
<h2>fixed</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child fixed">fixed</span>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
relative는 요소가 offset의 값만큼 이동한 것을 볼 수 있다.
relative에서 offset의 기준은 자기 자신인데 이 때 영점은 박스의 왼쪽 상단이라고 생각해야 한다.
기준점을 기준으로 위 그림처럼 움직이게 된다.
<!--offset 적용->
<!--position: absolute;-->
<!--css 파일은 위 예제와 같음-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<h2>static</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child_offset static" style="top: 40px; left: 40px">static <br>top: 40, left: 40</br></div>
<div class="sibling">sibling 2</div>
</div>
<h2>relative</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child_offset relative" style="top: 40px; left: 40px">relative <br>top: 40, left: 40</br></div>
<div class="sibling">sibling 2</div>
</div>
<h2>absolute</h2>
<div class="parent" style="position: relative">
<div class="sibling">Sibling 1</div>
<span class="child_offset absolute" style="top: 40px; left: 40px">absolute <br>top: 40, left: 40</br></span>
<div class="sibling">sibling 2</div>
</div>
<h2>fixed</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child fixed">fixed</span>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
absolute의 경우 부모 요소의 position을 기준으로 offset 값이 적용된다.
위 예제에서 부모 div 태그에 postion: relative;를 적용한 것은 absolute가 동작하는 것을 확인하기 위해서이다.
그렇다면 offset의 기준이 되는 부모 요소의 영점은 어디일까?
바로 패딩을 포함한 박스의 왼쪽 상단이다. 보더와 마진은 포함하지 않는다.
<!--offset 적용-->
<!--position: fixed;-->
<!--css 파일은 위 예제와 같음-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>position</title>
<link href="css/position.css" rel="stylesheet">
</head>
<body>
<h2>static</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child_offset static" style="top: 40px; left: 40px">static <br>top: 40, left: 40</br></div>
<div class="sibling">sibling 2</div>
</div>
<h2>relative</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<div class="child_offset relative" style="top: 40px; left: 40px">relative <br>top: 40, left: 40</br></div>
<div class="sibling">sibling 2</div>
</div>
<h2>absolute</h2>
<div class="parent" style="position: relative">
<div class="sibling">Sibling 1</div>
<span class="child_offset absolute" style="top: 40px; left: 40px">absolute <br>top: 40, left: 40</br></span>
<div class="sibling">sibling 2</div>
</div>
<h2>fixed</h2>
<div class="parent">
<div class="sibling">Sibling 1</div>
<span class="child_offset fixed" style="top: 100px; left: 80%">fixed <br>top: 40, left: 80%</br></span>
<div class="sibling">sibling 2</div>
</div>
</body>
</html>
fixed의 경우 뷰포트(브라우저)를 기준으로 offset 값이 적용된다.
그래서 부모의 position이 무엇이든 영향을 받지 않는다.
뷰포트에 고정되어 있기 때문에 스크롤을 움직여도 고정된 위치에 있게된다.
추가로 sticky라는 속성값을 position에서 사용할 수 있는데 브라우저 지원율이 좋지 않아 잘 사용하지 않는다.
w3schools에서 예제를 통해 어떻게 동작하는지 확인할 수 있다.
https://www.w3schools.com/cssref/tryit.php?filename=trycss_position_sticky
W3Schools online HTML editor
The W3Schools online code editor allows you to edit code and view the result in your browser
www.w3schools.com
그리고 offset은 top/left/bottom/right를 속성값으로 사용할 수 있다.
padding과 margin이 %단위를 사용할 때 상하좌우 관계없이 부모 요소의 width를 기준으로 하는 반면,
offset은 상하는 기준이 되는 요소의 height를 기준으로 하고 좌우는 기준이 되는 요소의 width를 기준으로 한다.
z-index
요소가 겹치는 순서(쌓이는 순서 또는 stack order)를 지정하는 속성이다.
auto는 기본값이며 쌓임 순서를 부모와 동일하게 설정한다.
number는 단위가 없는 수를 사용하며 해당 수치로 쌓임 순서를 결정한다. 음수도 사용 가능하다.
큰 값일 수록 가장 위에서부터 쌓이게 된다.
z-index는 부모 요소의 position이 static이 아닐 때만 사용가능하다.
만약 순서 값을 지정해주지 않으면 생성순서(코드순서)에 따라 쌓이게 된다.
w3schools에서 예제를 통해 z-index가 어떻게 동작하는지 확인할 수 있다.
myBox가 z-index: 1일 때 z-index가 0인 노란색 박스 위에 쌓이게 된다.
또, z-index는 부모가 z-index가 있을 경우 자식의 z-index는 부모 안에서만 의미가 있게 된다.
부모 요소들의 z-index가 먼저 계산되고 부모 요소 안에서 자식들의 z-index가 계산된다고 생각하면 된다.
아래 예제로 확인해보자.
<!--z-index 확인용 예제-->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>z-index</title>
<link href="css/zindex.css" rel="stylesheet">
</head>
<body>
<h1>z-index (Stacking Context)</h1>
<div id="div1" style="position: relative; z-index: 5;">
<strong>#1</strong><br>
<code>position: relative;<br>z-index: 5;</code>
</div>
<div id="div2" style="position: relative; z-index: 2;">
<strong>#2</strong><br>
<code>position: relative;<br>z-index: 2;</code>
</div>
<div id="div3" style="position: absolute; z-index: 4;">
<div id="div4" style="position: relative; z-index: 6;">
<strong>#4</strong><br>
<code>position: relative;<br>z-index: 6;</code>
</div>
<strong>#3</strong><br>
<code>position: absolute;<br>z-index: 4;</code>
<div id="div5" style="position: relative; z-index: 1;">
<strong>#5</strong><br>
<code>position: relative;<br>z-index: 1;</code>
</div>
<div id="div6" style="position: absolute; z-index: 3;">
<strong>#6</strong><br>
<code>position: absolute;<br>z-index: 3;</code>
</div>
</div>
</body>
</html>
/*zindex.css 파일*/
div {
opacity: 0.7;
padding: 10px;
margin: 10px;
width: 500px;
border: 1px dashed #696;
background-color: #5ae05a;
}
div > div {
width: 90%;
}
#div1 {
margin-bottom: 190px;
}
#div3 {
opacity: 1;
top: 80px;
left: 180px;
width: 400px;
padding-top: 50px;
background-color: yellow;
}
#div4, #div5 {
background-color: #ff8f00;
}
#div6 {
top: 20px;
left: 180px;
width: 150px;
height: 125px;
padding-top: 110px;
background-color: #e600ff;
}
html을 보면 #1, #2, #3이 body의 자식요소 이다. 그리고 #4, #5, #6이 #3의 자식 요소인 상태이다.
대충 훑어보면 이상한 점이 많다.
#4는 z-index가 6인데 z-index가 5인 #1보다 낮은 위치에 있다.
#5는 z-index가 1인데 z-index가 2인 #2보다 높은 위치에 있다.
위에서 말했듯이 z-index는 부모들 먼저 계산하고 자식들을 계산한다고 생각하면 된다.
body의 자식들인 #1, #2, #3을 먼저 계산해서 #2 -> #3 -> #1 순으로 놓는다.
그 다음 #3의 자식들인 #4, #5, #6을 계산해 #5 -> #6 -> #4 순으로 놓는다.
즉, #4, #5, #6은 #3에 속해있기 때문에 #1, #2와는 독립적인 관계이다.
부스트코스의 강의 내용을 정리한 포스트입니다.
https://www.boostcourse.org/cs120
비전공자를 위한 HTML/CSS
부스트코스 무료 강의
www.boostcourse.org
'공부 > HTML과 CSS' 카테고리의 다른 글
[미디어쿼리] 미디어 타입 & 미디어 특성 (0) | 2023.01.03 |
---|---|
[미디어쿼리] 미디어쿼리 소개 (0) | 2023.01.03 |
[CSS 속성] 레이아웃 (float, clear) (0) | 2022.12.29 |
[CSS 속성] 레이아웃 (display, visibility) (0) | 2022.12.28 |
[CSS 속성] 텍스트 (0) | 2022.12.27 |