2020. 11. 15. 22:48ㆍreact
Width를 100%로 했는데 왜 자꾸 100%가 넘어가지?
margin적용이 왜 안되는 거야...
css로 html 요소들을 배치할 때, 가끔 원하는 대로 height/width나 padding, margin 등이 설정되지 않는 경우가 있습니다. 이는 대부분 box model 개념 때문인 경우가 많습니다.
브라우저에서 각 태그들을 렌더링하고 배치할 때, CSS Box Model을 기준으로 레이아웃을 계산합니다. 이 Box Model은 content 영역, padding, board, margin으로 이루어집니다. 이 box model에 대해 알지 못하고 height/width, padding, border 등을 사용하면 원하는 대로 레이아웃 구성이 잡히지 않을 때가 있습니다. 이 글에서는 이와 관련하여 레이아웃을 설정할 때 알아두면 좋을 몇 가지 개념들을 알아보도록 하겠습니다.
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;
}
.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;
}
# 실제 렌더링 차이
<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가지 경우가 있습니다.
# 인접 형제 요소
인접 형제 요소의 경우 상하 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이 상쇄되어 가장 큰 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>
# 빈 블록
테두리(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>
# 상쇄 크기 결정
- 음수 값을 가진 바깥 여백을 포함할 경우, 상쇄된 여백의 크기는 제일 큰 양수 여백과 제일 작은(음의 방향으로, 절댓값이 제일 큰) 여백의 합이 됩니다.
- 모든 바깥 여백이 음수 값을 가질 경우, 상쇄된 여백의 크기는 제일 작은(음의 방향으로, 절댓값이 제일 큰) 여백의 크기가 됩니다. 인접 요소와 중첩 요소 모두에 적용됩니다.
'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 |