CSS 레이아웃 제어: 표준 흐름, 플로트 및 포지셔닝 완벽 가이드

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: 양쪽 플로트 불허

네 가지 해결 방법:

  1. 부모에 고정 높이 지정

    .father { height: 800px; }

    간단하지만 유연성이 떨어집니다.

  2. 빈 div 추가하여 clear

    <div class="clearfix"></div>
    
    .clearfix {
      margin: 0;
      padding: 0;
      clear: both;
    }

    간단하지만 불필요한 HTML 마크업이 생깁니다.

  3. overflow 속성 사용

    .father { overflow: hidden; }

    간단하지만 드롭다운 메뉴 등이 잘릴 수 있어 주의가 필요합니다.

  4. ::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>

태그: CSS 레이아웃 표준문서흐름 display float

6월 17일 18:33에 게시됨