1. 표준 문서 흐름 이해하기
HTML 요소는 기본적으로 두 가지 유형으로 나뉩니다:
- 블록 레벨 요소: 가로 전체 너비를 차지하며, 줄 바꿈이 발생합니다. 예:
h1~h6,p,div, 리스트 요소 - 인라인 요소: 내용 만큼의 너비만 차지하며, 같은 줄에 배치됩니다. 예:
span,a,img,strong
인라인 요소는 블록 요소 내부에 포함될 수 있지만, 반대는 불가능합니다.
2. display 속성으로 요소 유형 변경
<style>
div {
width: 100px;
height: 100px;
border: 1px solid red;
display: inline-block; /* 블록 속성을 유지하면서 인라인처럼 배치 */
}
span {
width: 100px;
height: 100px;
border: 1px solid yellow;
display: block; /* 블록 레벨 요소로 강제 변경 */
}
</style>
display 주요 값:
block: 블록 레벨inline: 인라인inline-block: 블록이지만 인라인처럼 한 줄에 배치none: 요소를 숨김 (공간도 제거됨)
3. float 속성으로 요소 띄우기
플로트를 사용하면 요소가 표준 흐름에서 벗어나 부모의 왼쪽 또는 오른쪽으로 배치됩니다.
<style>
.father {
border: 1px solid red;
}
.lay01, .lay02, .lay03 {
display: inline-block;
float: left;
margin: 10px;
padding: 5px;
}
.lay01 { border: 1px dashed yellow; }
.lay02 { border: 1px dashed blue; }
.lay03 { border: 1px dashed green; }
.lay04 {
border: 1px dashed gray;
font-size: 12px;
line-height: 23px;
display: inline-block;
}
</style>
<div class="father">
<div class="lay01"><img src="images/img1.png" alt=""></div>
<div class="lay02"><img src="images/img2.png" alt=""></div>
<div class="lay03"><img src="images/img3.png" alt=""></div>
<div class="lay04">플로트된 박스는 왼쪽이나 오른쪽으로 이동 가능합니다</div>
</div>
4. 부모 요소 높이 붕괴 문제 해결
자식 요소가 플로트되면 부모는 자식의 높이를 인식하지 못해 붕괴됩니다. clear 속성으로 해결합니다.
clear: left: 왼쪽 플로트 불허clear: right: 오른쪽 플로트 불허clear: both: 양쪽 플로트 불허
네 가지 해결 방법:
-
부모에 고정 높이 지정
.father { height: 800px; }간단하지만 유연성이 떨어집니다.
-
빈 div 추가하여 clear
<div class="clearfix"></div> .clearfix { margin: 0; padding: 0; clear: both; }간단하지만 불필요한 HTML 마크업이 생깁니다.
-
overflow 속성 사용
.father { overflow: hidden; }간단하지만 드롭다운 메뉴 등이 잘릴 수 있어 주의가 필요합니다.
-
::after 가상 요소 사용 (권장)
.father::after { content: ''; display: block; clear: both; }순수 CSS로 해결되며 부작용이 없어 가장 추천하는 방법입니다.
display vs float 비교:
display: 요소를 보이거나 숨기거나 유형을 변경하지만, 방향 제어는 불가float: 요소를 띄워 배치 방향을 제어하지만, 표준 흐름에서 벗어나므로 부모 붕괴 문제가 발생
5. CSS 포지셔닝
5.1 상대 위치 (relative)
자신의 원래 위치를 기준으로 이동하며, 원래 공간은 유지됩니다.
<style>
#box {
padding: 20px;
border: 1px solid red;
width: 300px;
height: 300px;
}
a {
width: 100px;
height: 100px;
text-decoration: none;
background: rgba(183, 0, 255, 0.99);
line-height: 100px;
text-align: center;
color: white;
display: block;
}
a:hover { background: #47a4ff; }
#a2 {
position: relative;
left: 200px;
top: -100px;
}
#a4 {
position: relative;
left: 100px;
top: -200px;
}
#a5 {
position: relative;
left: 200px;
top: -200px;
}
</style>
<div id="box">
<a href="#" id="a1">링크1</a>
<a href="#" id="a2">링크2</a>
<a href="#" id="a3">링크3</a>
<a href="#" id="a4">링크4</a>
<a href="#" id="a5">링크5</a>
</div>
5.2 절대 위치 (absolute)
가장 가까운 positioned 조상 요소(relative/absolute/fixed)를 기준으로 배치됩니다. positioned 조상이 없으면 <html>을 기준으로 합니다. 절대 위치 요소는 표준 흐름에서 완전히 제거되며, 원래 공간도 사라집니다.
<style>
div {
margin: 10px;
padding: 5px;
font-size: 12px;
line-height: 25px;
}
#father {
border: 1px solid red;
padding: 0;
}
#first {
background: rgba(170, 51, 68, 0.6);
border: 1px dashed #b27;
}
#second {
background: #255099;
border: 1px dashed #255066;
position: absolute;
right: 30px;
}
#third {
background: #1c6699;
border: 1px dashed #1c6615;
}
</style>
<div id="father">
<div id="first">첫 번째 박스</div>
<div id="second">두 번째 박스</div>
<div id="third">세 번째 박스</div>
</div>
5.3 고정 위치 (fixed)
뷰포트(브라우저 창)를 기준으로 고정됩니다. 스크롤해도 위치가 변하지 않습니다.
<style>
body { height: 900px; }
div:nth-of-type(1) {
width: 100px;
height: 100px;
background: red;
position: absolute; /* 뷰포트 기준, 스크롤 시 이동 */
right: 0;
bottom: 0;
}
div:nth-of-type(2) {
width: 50px;
height: 50px;
background: yellow;
position: fixed; /* 뷰포트에 고정, 스크롤 시에도 같은 위치 */
right: 0;
bottom: 0;
}
</style>
<div>div1</div>
<div>div2</div>
5.4 z-index와 쌓임 맥락
z-index는 positioned 요소의 쌓임 순서를 제어합니다. 값이 클수록 위에 표시되며, 기본값은 auto(0)입니다.
<style>
#content {
margin: 0;
padding: 0;
overflow: hidden;
font-size: 12px;
line-height: 25px;
border: 1px solid black;
width: 300px;
}
ul, li {
margin: 0;
padding: 0;
list-style: none;
}
#content ul {
position: relative;
}
.tipText, .tipBg {
position: absolute;
width: 300px;
height: 25px;
top: 124px;
color: white;
}
.tipBg {
background: black;
opacity: 0.5; /* 배경 투명도 */
}
.tipText {
/* z-index: 990; */ /* 더 큰 값으로 텍스트를 위로 */
}
</style>
<div id="content">
<ul>
<li><img src="images/01.png" alt=""></li>
<li class="tipText">마이크로서비스 학습하기</li>
<li class="tipBg"></li>
<li>시간</li>
</ul>
</div>