CSS
[css] height:100%를 줬는데 박스가 부모 박스보다 커지면 다음 문제를 체크하자
tea-tea
2024. 8. 11. 23:17
문제 상황과 해결방안
- 목적 | 레이아웃에서 부모 박스의 높이에 딱 맞는 자식 박스를 만들고 싶음.
- 행위 | 자식 박스에게 height:100%를 줌.
- 예상 | 자식이 부모의 padding을 제외한 높이에 딱 맞게 크기가 설정.
- 실제 | 부모 바깥으로 오버플로우됨.
일반적으로는 height 100%를 하면 당연히 부모의 안쪽에 이쁘게 채워질거라 하는데, 현실은 이렇게 오버플로우가 발생한다.
이럴 때는 아래의 css 부분들을 체크하자.
- 부모에 height가 설정되어 있지 않는 경우
- %단위값은 부모의 동일 속성 값을 상속한다. 부모에 height가 명시되어 있지 않거나 auto로 설정되어 있으면 자식 요소에 height:100%을 설정해도 동작하지 않는다.
- 자식에 box-sizing: border-box;이 아닌 경우
- box-sizing 속성은 요소의 높이를 명시할 때, padding과 border 값이 높이 설정에 고려될지를 정한다.
- box-sizing:content-box가 기본값이고, 이 값은 요소의 높이가 계산된 이후에 padding과 border가 추가된다. 따라서, 요소에 height:100%과 같이 사용하면 실제 높이는 (부모 높이 * 1) + (padding-top + padding-bottom ) + (border-width-top + border-width-bottom ) 으로 계산된다.
- box-sizing: border- box 를 설정하면 요소의 높이 계산에 padding과 border가 포함되므로, height:100%를 줄 때 padding과 border로 인한 오버플로우가 발생하지 않는다.
- 부모가 display:flex; flex-wrap:no-wrap; flex-shrink:1; flex-direction:column;이 아닌 경우
- box-sizing 으로 padding과 border가 height:100%에 포함될 수 있지만, margin은 그렇지 않다. 따라서, 자식 요소에 margin을 주면, 실제 높이는 (부모 요소의 높이 *1) + (margin-top + margin-bottom) 이다.
- margin을 높이 계산에 포함시켜주는 css 속성은 존재하지 않지만, 부모에 비해 오버플로우되는 크기를 줄여줄 방법은 존재한다.
- display:flex; 는 flex-wrap:no-wrap;과 flex-shrink:1;속성을 자동 설정한다. no-wrap은 자식 요소의 실제 높이가 부모보다 클 경우, 대상의 높이를 부모에 맞게 축소시키고, flex-shrink:1;은 다른 자식요소에 비해 상대적인 축소 비율을 설정한다.
- 이게 되어 있으면 margin으로 인한 overflow 문제를 해결할 수 있다.
- 부모가 overflow: visible로 설정되어 있는 경우(overflow 설정이 기본으로 되어 있는 경우)
- 내 경험상, 퍼블리싱 입문 및 주니어 단계에서는 발견하기 어려운 원인이다. mdn을 읽어도 알기 어려운 버그(?)에 가까운 문제이기 때문이다.(css는 공식 문서에 없는 동작방식으로 골치를 썪일 때가 힘들다...)
- overflow는 자식 요소가 오버플로우될 때 처리방식을 다룬다. 기본값은 visible로, 자식 요소의 오버플로우 부분을 표출한다. 이 값이 설정되어 있으면, 부모 요소의 높이는 오버플로우된 자식 요소의 높이에 맞춰 증가하려 한다. 그래서 부모 요소의 높이를 px같은 절대 단위로 명시하지 않고 %같은 걸로 명시하면 이 값을 무시하고 살짝? 늘어난다.(명시된 높이를 무시하고 조금 늘어나니 버그라 생각한다...)
- 따라서, visible 대신 auto나 hiddn, scroll, overlay 등을 설정하면 해결된다.
overflow 참고 자료: 실험했던 코드이다.
- 1번 사진 | 자식 박스에 내부 요소가 오버플로우되지 않을 땐, 부모의 높이에 맞게 height:100%가 정상 동작
- 2번 사진 | 자식 박스의 내부 요소가 오버플로우되니 높이가 늘어나며 부모 박스와 레이아웃이 어긋남
- 3번 사진 | 자식 요소에 overflow:scroll을 주니 높이가 정상 동작
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="box">
부모
<ul class="app">
자식
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
</body>
</html>
* {
box-sizing: border-box;
}
.box {
display: flex;
flex-direction: column;
height: 40vh;
background-color: gray;
}
.app {
margin: 15px;
/* margin: 0; */
overflow: auto;
display: flex;
flex-direction: column;
width: 500px;
list-style: none;
padding: 10px;
background-color: skyblue;
/* 고정 높이를 밖으면 괜찮은데, 그럴 일은 없음. 반응형이니까! */
/* height: 500px; */
height: 100%;
}
.item {
margin: 10px;
padding: 20px;
}
.item:nth-child(2n) {
margin: 10px;
background-color: rosybrown;
}
.item:nth-child(2n + 1) {
margin: 10px;
background-color: mediumpurple;
}