[CSS] 6. 레이아웃



6. 레이아웃

display - inline, block, inline-block

  • 요소들은 태어날 때부터 inline, block 이 정해진다.
  • 이 태생 값을 display 를 사용하여 변경할 수 있다.


inline

  • ex) span
  • 영역의 크기가 내부 콘텐츠 크기로 정해진다.
  • margin, padding 의 top, bottom을 주지 못한다. (반영이 안된다.)
  • 여러 요소가 가로 배치가 된다.


block

  • ex) div
  • 영역의 크기를 width, height으로 지정할 수 있다.
  • width 를 지정하지 않으면 가로 전체를 차지한다.
  • 여러 요소가 세로 배치가 된다.


inline-block

  • ex) input
  • 영역의 크기를 width, height 지정할 수 있다.
  • 여러 요소가 가로 배치가 된다.
span {
    display: block;
    width: 300px;
    height: 300px;
}



요소를 없애는 방법

<div class="box1"><div>
<div class="box2"><div>
<div class="box3"><div>

div {
    height: 200px;
}

.box1 {
    display: none;
    // 코드상으로는 존재하지만 눈에는 보이지 않음
    // 존재하지 않았던 것처럼 아에 레이아웃도 없음
    // 공간도 없다.
}
.box2 {
    visibility: hidden
    // 공간은 있지만 눈에 보이지 않는다.
}
.box3 {
    
}
  • display : none;
  • 레이아웃에서도 사라진다.
  • visibility: hidden
  • 레이아웃에는 숨겨지지 않지만 눈에 보이지 않음 (공간은 있다.)
  • 이 둘의 차이는 레이아웃에서 존재 하느냐 안하느냐


float

<div class="iamge"><div>
<p>
내용내용
</p>

// 그림이 위에 다 있고 p 가 아래
.image {
    width: 100px;
    height: 100px;
}

// 왼쪽 그림, 오른쪽 p
.image {
    width: 100px;
    height: 100px;
    float: left;
}

// 오른쪽 그림, 왼쪽 p
.image {
    width: 100px;
    height: 100px;
    float: right;
}
  • 요소를 둥둥 뜨게, 부유하도록 한다.
  • normal flow 로 부터 빠져서 별도의 배치 효과를 가질 수 있다.
  • normal flow : css 기본 설정된 블록 / 인라인 기본 계산 방법
  • float : none (내가 혼자 블록 다 차지한다.)
  • float: left; (나는 왼쪽에 있고 오른쪽에 다른 요소 흐르게 할 수 있다.)
  • float: right (나는 오른쪽에 있고 왼쪽에 다른 요소 흐르게 할 수 있다.)
  • flex 출시 이후 잘 사용하지 않는다.


position 과 Normal Flow

  • Normal Flow : 요소의 레이아웃을 변경하지 않았을 시, 자연스럽게 배치되는 방법
  • block은 block 으로, inline은 inline으로
  • position : static (기본값)


position - relative

<div><div>
<div id="box"><div>
<div><div>

div {
    width: 200px;
    height: 200px;
}

#box {
    position: relative;
    top: 50px;
    // 원래 normal flow 일때 자기 위치에서 50px 만큼 내려간다.
    left: 40px;
}
  • 요소를 normal flow에 따라 배치하고, 자기 자신을 기준으로 top, right, bottom, left의 값에 따라 오프셋을 적용
  • position: static일때는 top, right, bottom, left 사용 불가능
  • top, right, bottom, left 음수값 사용 가능
  • 다른 요소에는 영향을 주지 않는다.
  • top / bottom 같이 쓰면 top이 우선시
  • right / left 같이 쓰면 right가 우선시


position - absolute

<div><div>
<div id="box"><div>
<div><div>

div {
    width: 200px;
    height: 200px;
}

#box {
    position: absolute;
    // 아래있던 div 가 위로 올라온다.
    top: 50px;
    // 조상 중에서 position이 static이 아닌 요소를 찾아 기준점을 찾는다.
    // 현재 상황에선 body 가 기준이 된다.
    left: 40px;
}

// 아래의 경우 조상은 parent

<div><div>
<div id="parent">
    <div id="box"><div>
<div>
<div><div>

#parent {
    position: relative
}

#box {
    position: absolute;
    top: 50px;
    left: 40px;
}
  • 요소를 Normal flow에서 제거하고, 페이지 레이아웃에 공간도 배정하지 않는다.
  • 가장 가까운 위치의 부모를 찾아서 상대적으로 배치한다.
  • float 와 같이 공간 위에 붕 뜬다.
  • 조상 중에서 position이 static이 아닌 요소를 찾아 기준점을 찾는다.
  • absolute를 사용하고자 할때는 부모요소에 relative를 줘서 사용한다.
  • 부모중에 static인 요소가 없다면 body를 기준으로 한다.
  • 스크롤하면 부모따라서 변한다.


position - fixed

<div><div>
<div id="parent">
    <div id="box"><div>
</div>
<div><div>
<div><div>
<div><div>
<div><div>
<div><div>
<div><div>

#parent {
    position: relative
}

#box {
    position: fixed;
    bottom: 40px;
    right: 40px;
    // 뷰포트를 기준으로 동작한다.
    // 페이지업 버튼 같은 곳에서 사용한다.
}
  • 요소를 Normal flow에서 제거하고, 페이지 레이아웃에 공간도 배정하지 않는다.
  • 뷰포트의 초기 컨테이닝 블록을 기준으로 삼아 배치한다. (화면에 보이는 왼쪽 위 끝)
  • 뷰포트를 기준으로 동작한다.
  • 스크롤해도 변하지 않는다.


position - sticky

<div><div>
<div id="parent">
    <div id="box"><div>
</div>
<div><div>
<div><div>
<div><div>
<div><div>


#parent {
    position: sticky;
    top: 100px;
    left: 100px;
}

#box {
    position: sticky;
    top: 100px;
    left: 100px;
    // 여기에 sticky 주면 적용되지 않는다.
    // 스크롤되는 주체(body)의 바로 하위 자식이어야 한다.
}

  • normal flow에 따라 배치하고, 스크롤시, 가장 가까운 스크롤 되는 조상을 따라간다.
  • 스크롤 하기전에는 normal flow로 있다가
  • 스크롤 해서 내리면 fixed와 같이 고정된 그 위치에 있는다.
  • top, left … 기준점은 뷰포트
  • 스크롤되는 조상의 하위여야 한다. (하위의 하위 안된다.)


overflow

<div>
매우 긴 예시문장이 있다고 가정해보자
<br>
여기도 매우 긴 문장이 있다고 생각하자
</div>
<h1>넘쳐흐른곳이랑 겹치겠지</h1>

div {
    width: 10px;
    height: 10px;
    // 컨텐츠가 더 많으니 넘쳐흐를 것임
    // 하지만 영역을 차지하는 것은 아님
    // h1과 겹치게 될 것임
}

  • 요소의 width, height보다 contents 내용이 더 클 때
  • overflow: visible (default) - 넘쳐흐르는 부분이 보인다.
  • overflow: hidden - 넘쳐흐른부분 안보인다.
  • overflow: scroll - 스크롤해서 보여진다.
  • overflow: auto - 넘치치 않으면 visible, 넘치면 scroll


z-index

<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>

div {
    width: 150px;
    height: 150px;
}

#box2, #box3 {
    margin-top: -40px;
}

#box2 {
    margin-left: 40px;
}

// 3 > 2 > 1

#box2 {
    margin-left: 40px;
    position: relative;
    // 2번이 가장 위에 나타남
}

#box3 {
    position: relative;
    // 원래 코드 순서대로 3 > 2 > 1
}

// 이 상태에서

#box2 {
    margin-left: 40px;
    position: relative;
    z-index: 1;
    // 2번이 가장 위
}

#box3 {
    position: relative;
    // 아니면
    z-index: -1;
}


  • z축의 개념을 추가하는 것
  • 앞, 뒤 요소가 쌓이는 순서를 지정하는 것
  • z-index : auto (기본값)
  • integer 값 넣을 수 있다.
  • 원래 순서는 코드 순서로 쌓이고, static이 아닌 요소가 static 요소 위에 쌓인다.
  • 무조건 최상위로 뜨게 하고 싶으면 z-index 엄청 크게 주기


나의 회고 🤫

항상 헷갈렸던 relative와 absolute를 짚고 넘어갈 수 있는 좋은 시간이었다.
normal flow라는 개념도 처음 알게 되었고, position이 static이 아닌 경우가 더 z-index 측면에서 우선순위가 높다는 사실도 처음 알게 되었다…!
나는 정말 왜이렇게 모르는게 많았을까…따흐흑
또 css 를 적용하다보면 z-index가 무자비하게 100 등의 숫자로 앞에 나와있는 경우를 자주 보고,
그걸 유지보수 하는 과정에서 나는 1000 이런 숫자를 많이 썼었는데 지금 생각하니 너무 부끄럽다…
오늘 배운 개념 잊지 말고 잘 활용해서 css 도 클린코드로 작성해야겠다!