CSS

박스모델

프도의길 2021. 9. 20. 00:20

모든 콘텐츠는 고유한 영역이 있습니다.

 

[그림] HTML 문서의 레이아웃

 

모든 콘텐츠는 각자의 영역을 가지며, 일반적으로 하나의 콘텐츠로 묶이는 엘리먼트(요소)들이 하나의 박스가 됩니다.

박스는 항상 직사각형이고, 너비(width)와 높이(height)를 가집니다. CSS를 이용해 속성과 값으로 그 크기를 설정합니다. 다음 예제에 width, height 속성을 넣어 테스트해보세요.

* 박스가 차지하는 영역을 시각적으로 확인하기 위해 배경색을 꼭 넣으세요!

<h1>Basic document flow</h1> <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p> <p>By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p> <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p> <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not</p>[코드] HTML 예시
h1 {

background: gray; width: 60%;

}

p {

background: rgba(255,84,104,0.3); width: 80%; height: 200px;

}

span {

background: yellow; width: 100px; height: 100px;

} CSS 예시

 

질문

  • 위 HTML에서 줄바꿈이 적용되는 태그는 무엇인가요? 줄바꿈이 적용되지 않은 태그는 무엇인가요?
  • 위 CSS 코드에서 실제로 작동하지 않는 것이 존재합니다. 무엇일까요?

줄바꿈이 되는 박스(block) vs. 옆으로 붙는 박스(inline, inline-block)

박스의 종류는 줄바꿈이 되는 박스와 줄바꿈이 없이 옆으로 붙는 박스로 구분할 수 있습니다. 줄바꿈이 되는 박스는 block 박스, 줄바꿈이 일어나지 않고, 크기지정을 할 수 없는 박스는 inline 박스라고 부릅니다. 그리고 이 두가지 박스 종류의 특징이 섞인, 줄바꿈이 일어나지 않는 동시에 block 박스의 특징을 가지는 inline-block 박스도 있습니다.

위 예제에서, 줄바꿈이 되는 태그와 그렇지 않은 태그는 무엇이었나요?

정답

  • 위 HTML에서 줄바꿈이 되는 태그는 무엇인가요? 줄바꿈이 적용되지 않은 태그는 무엇인가요?
    • 줄바꿈이 되는 태그: <h1> <p>
    • 줄바꿈이 되지 않는 태그: <span>

정답을 통해, <h1> <p> 등은 block 박스이며, <span>은 inline 박스임을 알 수 있습니다. 작성한 태그가 어떤 박스인지 어떻게 확인할 수 있을까요? 크롬 브라우저에서 단축키 F12, Ctrl + Shift + i, 또는 Cmd + Opt + i(MacOS)를 입력해 개발자 도구를 열고, 개발자도구의 Elements 탭에서 이 내용을 확인할 수 있습니다. block 요소의 목록은 MDN block 엘리먼트 목록을 통해, inline 요소의 목록은 inline 엘리먼트 목록을 통해 확인할 수 있습니다.

다음은 Block level element 입니다.

[그림] 크롬 개발자 도구의 Elements 탭에서 확인한 블록 요소

 

다음은 Inline level element 입니다.

[그림] 크롬 개발자 도구의 Elements 탭에서 확인한 인라인 요소

 

* 각 태그가 어떤 요소인지 무작정 외우는 것 보다는, 개발하면서 자연스럽게 익히길 권장합니다.

* Block 요소의 대표적인 예는 <div>, <p> 입니다.

* Inline 요소의 대표적인 예는 <span>입니다.

두번째 질문에 대한 정답을 알아봅시다. 어떤 태그에는 CSS의 width, height 등 박스의 크기를 설정하는 속성이 작동하지 않는 경우가 있습니다.

정답

  • 위 CSS 선언 중 실제로 작동하지 않는 것이 존재합니다. 그게 무엇인가요?
    • <span>

위 예제에서 <span> 태그의 경우는 width, height 속성이 적용되지 않습니다. block 박스와는 다르게 inline 박스는 width, height 속성이 적용되지 않습니다. 이번엔 위 CSS에서 span에 대한 속성을 다음과 같이 바꿔보겠습니다.

span {

background: yellow; display: inline-block; width: 100px; height: 100px;

}//CSS에서 span 태그에 'display: inline-block'을 추가합니다.

변경사항은 codepen에서 확인할 수 있습니다.

inline-block 박스는 inline 박스처럼 다른 요소의 옆으로 붙으면서, 자체적으로 고유의 크기를 가집니다. 이 세 가지 박스의 특징을 정리해 보겠습니다.

[그림] span 태그에 display 속성을 추가하고, 값으로 inline-block을 지정합니다.

 

blockinline-blockinline

줄바꿈 여부 줄바꿈이 일어남 줄바꿈이 일어나지 않음 줄바꿈이 일어나지 않음
기본적으로 갖는 너비(width) 100% 글자가 차지하는 만큼 글자가 차지하는 만큼
width, height 사용 가능여부 가능 가능 불가능

[표] block, inline-block, inline의 특징




박스를 구성하는 요소

CSS 박스 모델은 다음 그림만 기억하면 됩니다.

[그림] border(테두리)를 기준으로 padding(안쪽 여백)과 margin(바깥 여백)이 있습니다.

 

border (테두리)

테두리는 심미적인 용도 외에도, 개발 과정에서도 매우 의미있게 사용합니다. 각 영역이 차지하는 크기를 파악하기 위해, 레이아웃을 만들면서 그 크기를 시각적으로 확인할 수 있도록 만듭니다. 다음의 코드를 통해 테두리를 실선으로 확인할 수 있습니다.

p {

border: 1px solid red;

}//p태그에 1px의 빨간색 실선을 추가합니다.

border 속성에 적용된 각각의 값은 테두리 두께(border-width), 테두리 스타일(border-style), 테두리 색상(border-color)입니다. 괄호 안에 적힌 것들이 바로 border 속성에 추가할 수 있는 세부 속성입니다. 이외에도 border-style mdn과 같이 구글에 검색하면, 테두리 스타일에 대한 다양한 세부 속성을 찾아볼 수 있습니다.

질문

  • 테두리를 점선으로 만들고 싶으면 어떻게 해야 할까요? border-style의 값 중 하나를 바꿔보세요.
  • 테두리를 둥근 모서리로 만들 수도 있습니다. 어떤 속성을 사용하면 되나요? 참고로, border 속성만으로는 둥근 모서리를 만들 수 없습니다.
  • 박스 바깥쪽에 그림자를 넣을 수도 있습니다. 어떤 속성을 사용하면 되나요? 참고로, 그림자를 명확하게 보기 위해서는 background 속성이 불투명해야 합니다.

margin (바깥 여백)

각각의 값은 top, right, bottom, left로 시계방향입니다.

p {

margin: 10px 20px 30px 40px;

}// p태그의 상하좌우에 여백을 추가합니다.

크롬 개발자 도구의 Elements 탭에서 위의 코드가 어떻게 적용되는지 확인할 수 있습니다. margin은 주황색으로 표현됩니다.

[그림] 크롬의 개발자 도구를 이용해 margin 영역을 확인할 수 있습니다.


값을 두개만 넣으면 top과 bottom이 10px, left 및 right가 20px 입니다.

p {

margin: 10px 20px;

}// p태그의 위아래와 좌우에 각각 여백을 추가합니다.

값을 하나만 넣으면 모든 방향의 바깥 여백에 적용됩니다.

p {

margin: 10px;

}//p태그의 모든 방향에 여백을 추가합니다.

물론 다음과 같이 방향을 특정한 속성도 존재합니다.

p {

margin-top: 10px; margin-right: 20px; margin-bottom: 30px; margin-left: 40px;

}// margin의 위치를 특정해 여백을 추가할 수 있습니다.

* 위와 같은 규칙은 padding에도 동일하게 적용됩니다.

재미있게도 바깥 여백에는 음수값을 지정할 수 있습니다. 여백에 음수 값을 지정하면 다른 엘리먼트와의 간격이 줄어듭니다. 극단적으로 적용하면, 화면(viewport)에서 아예 사라지게 하거나, 다른 엘리먼트와 겹치게 만들 수도 있습니다.

p {

margin-top: -2rem;

}// p태그의 margin-top 속성에 음수 값을 지정합니다.

변경사항은 codepen에서 확인할 수 있습니다.

 

padding (안쪽 여백)

padding은 border를 기준으로 박스 내부의 여백을 지정합니다. 값의 순서에 따른 방향은 margin과 동일하게 top, right, bottom, left입니다.

p {

padding: 10px 20px 30px 40px;

}// p태그의 padding 속성에 여백을 추가합니다.

배경색이나 border를 적용하면, 안쪽 여백을 더욱 선명하게 확인할 수 있습니다.

p {

padding: 10px 20px 30px 40px; border: 1px solid red; background-color: lightyellow;

}//p태그에 border, background-color 속성을 추가합니다.

크롬 개발자 도구의 Elements 탭에서 다음 그림과 같은 모양을 확인할 수 있습니다. padding은 초록색으로 표현됩니다.

[그림] 크롬의 개발자 도구를 이용해 padding 영역을 확인할 수 있습니다.



박스를 벗어나는 컨텐츠 처리

박스의 height 속성에 콘텐츠가 차지하는 공간보다 작은 값을 지정하세요. 컨텐츠가 박스 바깥으로 빠져나오나요? 아니면 박스에 맞게 가려지나요?

p {

height: 40px;

}// p태그의 height 속성에 콘텐츠가 차지하는 높이보다 작은 값을 할당합니다.

박스 크기보다 콘텐츠 크기가 더 큰 경우에는 콘텐츠가 박스 바깥으로 빠져나옵니다. 그러나 이런 상황을 원하는 사람은 거의 없을 겁니다. 이렇게 콘텐츠가 박스를 뚫고 나가는 경우에는 박스 크기에 맞게 콘텐츠를 더이상 표시하지 않거나, 혹은 박스 안에 스크롤을 추가하여 콘텐츠를 확인할 수 있게 만듭니다.

p {

height: 40px; overflow: auto;

}//p태그에 overflow 속성을 지정해 박스보다 큰 콘텐츠에는 스크롤을 표시합니다.

변경사항은 codepen에서 확인할 수 있습니다.

overflow 속성의 auto 값은, 콘텐츠가 넘치는 경우 스크롤을 생성하도록 합니다. 다른 경우에는 넘치는 콘텐츠의 내용을 보여주고 싶지 않을 수 있습니다. 이 때에는 overflow 속성에 hidden 값을 사용합니다. overflow 속성은 x축과 y축을 지정해 가로 방향으로 스크롤하거나 세로 방향으로 스크롤 할 수 있게끔 지정할 수 있습니다. overflow-x 속성과 overflow-y 속성을 이용하면 두 방향을 모두 지정할 수 있습니다.

 

박스 크기 측정 기준

박스 크기를 측정하는 기준은 매우 중요합니다. 예제를 보며 함께 살펴봅니다.

<div id="container">

   <div id="inner">

      안쪽 box

   </div>

</div>// html 예시
#container {

width: 300px;

padding: 10px;

background-color: yellow;

border: 2px solid red;

}

#inner {

width: 100%;

height: 200px;

border: 2px solid green;

background-color:

lightgreen;

padding: 30px;

}//CSS 예시

변경사항은 codepen에서 확인할 수 있습니다.

혹시 어떤 부분이 문제인지 알겠나요? id가 container인 박스의 width 속성에 300px을 지정했습니다. 그러나 개발자도구로 확인한 해당 요소의 width 값은 324px 입니다. CSS에서 지정한 두 요소에 대해 아래와 같이 확인할 수 있습니다.

  • #container의 너비는 300px이 아니라, 324px입니다. 브라우저는 다음과 같은 계산을 실행합니다. 300px (콘텐츠 영역) + 10px (padding-left) + 10px (padding-right) + 2px (border-left) + 2px (border-right)
  • #inner의 100%는 300px이 아니라, 364px입니다. 브라우저는 다음과 같은 계산을 실행합니다. 300px (300px의 100%) + 30px (padding-left) + 30px (padding-right) + 2px (border-left) + 2px (border-right)

처음 레이아웃 디자인을 할 때 가장 많이하는 실수가 있습니다. 박스에 적용할 여백을 고려하지 않고 박스의 크기를 디자인하는 경우입니다. 박스의 크기를 디자인할 때 콘텐츠 영역만 고려하면, 개발 과정에서 처음 생각한 레이아웃을 벗어날 수 있습니다. 여백을 고려하지 않은 계산 방식은 레이아웃 디자인을 어렵게 만듭니다.

레이아웃 디자인을 조금 더 쉽게하는 방법이 있습니다. 여백과 테두리 두께를 포함한 박스 계산 법입니다. *은 모든 요소를 선택하는 셀렉터입니다. 모든 요소를 선택해 box-sizing 속성을 추가하고, border-box라는 값을 추가합니다.

* {

box-sizing: border-box;

}// 모든 요소에 'box-sizing: border-box'를 추가합니다.

변경사항은 codepen에서 확인할 수 있습니다.

이렇게 모든 요소에 box-sizing: border-box를 적용하면, 모든 박스에서 여백과 테두리를 포함한 크기로 계산됩니다. 일반적으로 box-sizing은 HTML 문서 전체에 적용합니다. box-sizing을 일부 요소에만 적용하는 경우, 혼란을 가중시킬 수 있습니다. 앞으로 레이아웃과 관련된 이야기를 할 때에는 border-box 계산법을 기준으로 이야기합니다. 박스 크기 측정 기준 두가지를 항상 염두해주세요.

* content-box는 박스의 크기를 측정하는 기본값입니다. 그러나 대부분의 레이아웃 디자인에서 여백과 테두리를 포함하는 박스 크기 계산법인 border-box를 권장합니다.

 

'CSS' 카테고리의 다른 글

FlexBox로 레이아웃 잡기  (0) 2021.09.21
CSS중급 레이아웃: 화면을 나누는 방법  (0) 2021.09.21
CSS 텍스트 꾸미기  (0) 2021.09.20
CSS 기본적인 셀렉터  (0) 2021.09.19
CSS 소개  (0) 2021.09.19