CSS에는 크게 2가지 유형의 박스가 있다.
block 박스와 inline 박스이다.
이 유형은 페이지 흐름 및 페이지 내의 다른 박스와 관련하여 작동하는 방식을 나타낸다.
박스는 inner display type과 outer display type을 가진다.
outer display type은 박스 외부의 엘리먼트들과의 위치 관계를 나타내는걸 뜻하고
inner display type은 박스 내부의 엘리먼트들의 레이아웃을 나타낸다.
일반적으로 display
프로퍼티를 이용해서 display type의 다양한 값을 설정할 수 있다.
예를 들어, display 프로퍼티의 값이 block이라면 outer display type은 block, inner display type은 normal flow로서 박스 내부의 엘리먼트들은 block박스 또는 inline박스로서 동작한다.
또 다른 예를 들어, display 프로퍼티의 값으로 flex
를 가진다면 그 박스의 outer display type은 block, inner display type은 flex로 변경된다.
만약 박스가 outer display type으로 block을 가진다면 다음의 특성을 지닌다.
그 박스는 새 줄을 만든다.
width
와 height
프로퍼티가 작동한다.
Padding, margin and border가 다른 엘리먼트들에게 영향을 줘서 밀어낸다.
상자는 인라인방향(가로방향)으로 확장되어 부모박스의 컨테이너에서 사용 가능한 공간을 채운다.
일부 HTML 엘리먼트들은(<p>
, <h1>
과 같은) 기본적으로 block을 outer display type으로 사용한다.
만약 박스가 outer display type으로 inline을 가진다면 다음의 특성을 지닌다.
박스가 새 줄을 만들지 않고 현재 줄에서 이어진다.
width
와 height
프로퍼티가 무시된다.
수직 padding, 수직 margin, 수직 borders이 적용되지만 다른 inline박스에게 영향을 주지않아서 밀어내지 않는다.
수평 padding, 수평 margin, 수평 borders가 다른 inline박스에게 영향을 줘서 밀어낸다.
일부 HTML 엘리먼트들은(<a>
, <span>
, <em>
, <strong>
과 같은) 기본적으로 inline을 outer display type으로 사용한다.
박스는 또한 inner display type을 갖는다.
Inner display type은 박스내부의 엘리먼트들의 레이아웃을 나타낸다.
block과 inline의 레이아웃은 웹에서 동작하는 기본 방식이다.
따라서 다른 명령이 없는 한 기본적으로 박스 내부의 엘리먼트도 normal flow로 배치되며 내부 엘리먼트의 block박스 또는 inline박스로서 동작한다.
엘리먼트에 display: flex
를 설정해서 inner display type을 변경할 수 있다.
그 엘리먼트는 outer display type으로 block을 사용하지만, inner display type은 flex로 변경된다.
해당 엘리먼트의 다이렉트 자식들은 flex item이 되며 Flexbox의 명세에 따라 위치된다.
엘리먼트에 display: inline-flex
를 설정하면 outer display type으로 inline을 사용하고, inner display type은 flex로 변경된다.
더 디테일하게 들어가서 공부해보면 flex나 grid같은 다양한 inner value가 있다는 것을 알 수 있다.
CSS 박스 모델은 block박스에 적용되며 inline박스에는 일부만 적용된다.
위의 outer display type을 살펴보면 inline박스는 block박스와 작동이 살짝 다른걸 볼 수 있다.
Content box
Padding box
Border box
Margin box
박스 모델에는 표준 박스 모델과 대체 박스 모델이 있다.
브라우저는 기본적으로 표준 모델을 사용한다.
표준 박스 모델에서는 inline-size
와 block-size
또는 width
와 height
를 사용해서 content box의 사이즈를 조정할 수 있다.
inline-size
와block-size
가 생소할 것이다.
이 프로퍼티는writing-mode
프로퍼티에 의존하며 현재의 상황에선 너비와 높이를 뜻한다.
writing-mode
는 왼쪽에서 오른쪽, 위에서 아래로와 같은 블록단위의 출력 방향을 정의하는 프로퍼티이다.
다음과 같이 css가 주어졌다고 가정해보자.
.box {
width: 350px;
height: 150px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
너비는 410px(350 + 25 + 25 + 5 + 5)가 된다.
높이는 210px(150 + 25 + 25 + 5 + 5)가 된다.
대체 박스 모델에서 width
는 페이지에 보여지는 상자의 실제 너비를 뜻한다.
box-sizing: border-box
로 대체 박스 모델로 바꿀 수 있다.
다음과 같이 css가 주어졌다고 가정해보자.
.box {
width: 350px;
inline-size: 350px;
height: 150px;
block-size: 150px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
box-sizing
은 상속 불가능한 프로퍼티이므로 대체 박스 모델로 적용하고 싶다면 다음과 같이 작성한다.
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
위 아래로 여백이 맞닿아 있다면 마진 충돌이 일어난다.
이때 두 엘리먼트의 마진이 양수인지 음수인지에 따라 결과가 달라진다.
둘 다 양수인 margin : 큰 margin이 적용된다.
둘 다 음수인 margin : 작은 margin(0에서 먼)이 적용된다.
부호가 다른 margin : 합산한 값이 적용된다.
display: inline-block
은 인라인과 블록 사이의 중간 지점을 제공하는 특별한 display value다.
항목을 새 줄로 구분하지 않고 너비와 높이를 유지하고 위에 표시된 항목과 겹치지 않도록 하려면 이 항목을 사용합니다.
이 기능은 패딩을 추가하여 링크에 더 큰 히트 영역을 제공하려는 경우에 사용된다.
다음 그림은 inline-block이 적용되지 않은 navbar이다.
<a>
가 inline 박스이기 때문에 수직 패딩 마진이 다른 엘리먼트들에게 영향을 주지 않아서 부모 엘리먼트인 <ul>
위로 튀어나와 있다.
<a>
엘리먼트에 inline-block
를 적용하면 다음과 같이 변한다.
[참고] : MDN