CSS Box model

2020. 11. 15. 22:48react

Width를 100%로 했는데 왜 자꾸 100%가 넘어가지?

margin적용이 왜 안되는 거야...

 

CSS 기본 박스 모델 입문

문서의 레이아웃을 계산할 때, 브라우저의 렌더링 엔진은 표준 CSS 기본 박스 모델에 따라 각각의 요소를 사각형 박스로 표현합니다. CSS는 박스의 크기, 위치, 속성(색, 배경, 테두리 모양 등)을

developer.mozilla.org

 css로 html 요소들을 배치할 때, 가끔 원하는 대로 height/width나 padding, margin 등이 설정되지 않는 경우가 있습니다.  이는 대부분 box model 개념 때문인 경우가 많습니다.

 브라우저에서 각 태그들을 렌더링하고 배치할 때, CSS Box Model을 기준으로 레이아웃을 계산합니다. 이 Box Model은 content 영역, padding, board, margin으로 이루어집니다. 이 box model에 대해 알지 못하고 height/width, padding, border 등을 사용하면 원하는 대로 레이아웃 구성이 잡히지 않을 때가 있습니다. 이 글에서는 이와 관련하여 레이아웃을 설정할 때 알아두면 좋을 몇 가지 개념들을 알아보도록 하겠습니다.

 

css box model

 


 

Box sizing

# content-box / border-box

 css 요소들이 렌더링 될 때 css box model의 높이(height)나 넓이(width)는 content크기, padding, border에 의해서 결정되며, box-sizing 속성에 따라서, heigth 또는 width 속성의 적용 방식이 달라집니다. box-sizing 속성은 크게 'border-box' 'content-box'가 있으며 기본값은 content-box입니다.

 

  • content-box의 경우 heigth, width 값은 content의 크기가 됩니다. 때문에 content-box가 실제로 그려지는 크기는  height/width 값과 padding, border의 크기를 합친 값이 됩니다.
  • border-box의 경우 height, width 값은 실제로 그려지는 크기가 되며, height/width 값에서 padding, border의 크기를 빼면 content의 크기가 됩니다.
.border-box {
  box-sizing: border-box;
  height: 40px;
  border: 4px solid #6d6d6d;
  padding: 10px 10px 10px 10px;
}

.content-box {
  box-sizing: content-box;
  height: 40px;
  border: 4px solid #6d6d6d;
  padding: 10px 10px 10px 10px;
}

[hegith of box model]

 

.border-box {
  width: 100px;
  border: 4px solid #6d6d6d;
  padding: 10px 10px 10px 10px;
  box-sizing: border-box;
}

.content-box {
  width: 100px;
  border: 4px solid #6d6d6d;
  padding: 10px 10px 10px 10px;
  box-sizing: content-box;
}

[width of box model]

 

# 실제 렌더링 차이

<style>
	.outer {
        background-color: white;
        width: 300px;
        height: 300px;
    }

    .outer div {
        background-color: green;
        margin-bottom: 20px;
    }

    .outer .content {
        box-sizing: content-box;
        width: 100%;
    }

    .outer .border {
        box-sizing: border-box;
        width: 100%;
    }

    .outer .extra {
        border: solid #5B6DCD 10px;
        padding: 10px;
    }
</style>

<div class="outer">
  <div class="content">
  	content-box without padding & border
  </div>

  <div class="content extra">
  	content-box with padding & border
  </div>

  <div class="border extra">
  	border-box with padding & border
  </div>
</div>

 이러한 css box model에 대한 개념을 잘 인식하고 box-sizing 방식을 잘 선택함으로써, 각 요소들을 원하는 height/width나 padding 및 border 크기로 렌더링 할 수 있습니다.

 

 


 

여백 상쇄

 각 요소들은 margin 값에 의해서 각각 여백을 가지게 됩니다. 이 여백을 지정할 때 Vertical(위 또는 아래) margin은 경우에 따라서 제일 큰 여백의 값을 결합(상쇄)됩니다. 단, 플로팅 요소나 절대 위치 지정(absolute, fixed) 요소는 여백이 상쇄되지 않습니다. 여백이 상쇄되는 경우는 인접 형제 요소, 부모와 자손을 분리할 컨텐츠가 없음, 빈 블록 이 3가지 경우가 있습니다.

 

여백 상쇄 정복 - CSS: Cascading Style Sheets | MDN

여러 블록의 위쪽 및 아래쪽 바깥 여백(마진)은 경우에 따라 제일 큰 여백의 크기를 가진 단일 여백으로 결합(상쇄)되곤 합니다. 이런 동작을 여백 상쇄라고 부릅니다. 단, 플로팅 요소와 절대 위

developer.mozilla.org

 

# 인접 형제 요소

인접 형제 요소의 경우 상하 margin은 서로 상쇄됩니다. (단, 뒤쪽 형제 요소가 플로팅을 해제해야 하는 경우는 예외)

<style>
	.margin-brother {
        background-color: white;
        margin-bottom: 50px;
    }

    .margin-brother p {
        background-color: green;
        height: 40px;
        margin: 20px
    }
</style>

<div class="margin-brother">
  <p>형제 요소1</p>
  <p>형제 요소2</p>
</div>

상하 margin의 합이 40px이지만, 상쇄되어 여백이 20px가 된다.

 

# 부모와 자손을 분리할 컨텐츠 없음

 간단하게 말해서 부모 요소와 자식 요소 간에 경계가 확실하지 않을 때 서로 margin이 상쇄되어 가장 큰 margin 값이 부모 요소에 적용됩니다.

 

 부모 블록에 테두리(border), 안쪽 여백(padding), 인라인 부분이 없고 블록 서식 맥락이 생성되지 않았으며 부모의 margin-top을 자식의 margin-top과 분리할 권한이 없는 경우.

 

 또는, 부모 블록에 테두리(border), 안쪽 여백(padding), 인라인 컨텐츠가 없으며, 부모의 margin-bottom과 자식의 margin-bottom을 분리할 heght, min-height, max-height가 존재하지 않는 경우 부모와 자식의 여백이 상쇄됩니다.

 

상쇄된 여백은 부모의 여백 값이 됩니다.

 

<style>
    .margin-parent {
        background-color: white;
        margin-top: 10px;
        margin-bottom: 10px;
    }

    .margin-parent p {
        height: 40px;
        margin-top: 40px;
        margin-bottom: 40px;
        background-color: green;
    }

    .border {
        border: 1px solid #ff00ff
    }
</style>

<p>Above of div</p>
<div class="margin-parent">
  <p>자식 요소</p>
</div>
<p>under of div</p>

<p>Above of div</p>
<div class="margin-parent border">
  <p>자식 요소</p>
</div>
<p>under of div</p>

자식요소와 부모요소의 margin이 상쇄되어 부모요소에게 둘 중 가장 큰 margin 값 적용
자식요소와 부모요소가 분리되어 각각 margin이 적용

 

 

# 빈 블록

 테두리(border), 안쪽 여백(padding), 인라인 콘텐츠, height, min-height, max-height가 없으면, 즉 렌더링 결과물이 비어 있으면, 해당 블록의 margin-top과 margin-bottom은 서로 상쇄됩니다.

<style>
    .margin-empty {
        background-color: white;
        margin-bottom: 50px;
    }

    .margin-empty p {
        background-color: green;
        height: 40px;
        margin: 0;
    }

    .margin-empty div {
        margin-top: 20px;
        margin-bottom: 20px;
    }
</style>

<div class="margin-empty">
  <p>형제 요소1</p>
  <div></div>
  <p>형제 요소2</p>
</div>

<div>의 margin-top과 margin-bottom이 상쇄되어 총 20px의 여백만 생성

 

# 상쇄 크기 결정

  • 음수 값을 가진 바깥 여백을 포함할 경우, 상쇄된 여백의 크기는 제일 큰 양수 여백과 제일 작은(음의 방향으로, 절댓값이 제일 큰) 여백의 합이 됩니다.
  • 모든 바깥 여백이 음수 값을 가질 경우, 상쇄된 여백의 크기는 제일 작은(음의 방향으로, 절댓값이 제일 큰) 여백의 크기가 됩니다. 인접 요소와 중첩 요소 모두에 적용됩니다.

'react' 카테고리의 다른 글

React event의 여러가지 target  (0) 2023.11.19
box-shadow로 inline border 만들기  (0) 2023.11.13
CSS BoxShadow 제대로 알기  (0) 2023.11.06
html input 유효성(validity) 검사  (2) 2023.10.14
input요소 checkValidity와 reportValidity  (0) 2023.10.13