본문으로 바로가기

CSS 박스 모델 크기 #2

category 웹코딩/CSS 2015. 6. 15. 11:00

각 종류의 박스를 지정한 크기로 표시하고, 내용에 맞춰 자동 축소시키고, 부모 요소에 맞춰 자동 확대시키기 위해 어떤 식으로 너비와 높이를 지정하는 법을 설명합니다.

박스 모델 너비

width 속성은 인라인을 제외한 모든 요소에 적용되는데 요소 종류에 따라 다르게 적용되며 위치 및 플로트에 따라서도 다르게 적용한다. height 속성과는 독립적이며 기본값은 width: auto이다.

  • width: auto
    • 자동 축소 : left: auto, right: auto, width: auto일때, 블록 박스를 제외한 모든 박스 모델이 자동 축소된다.
    • 자동 확대 : left: 0, right: 0, width: auto일때, 블록 박스, 절대 박스는 자동 확대된다.
  • width: 크기지정 : 요소에 너비를 지정할때는 사용자의 화면을 고려해서 크기를 지정한다. 레이아웃을 유연하게 하려면 백분율을 사용한다.
  • width: 100% : width: 100%을 지정하면 요소가 부모 요소의 너비에 맞춰 늘어나긴 하지만 auto를 지정한 것과 달리 페이지를 처음 불러올 때에만 자동으로 늘어난다. 요소에 가로 마진, 테두리, 패딩을 지정하면 그 요소의 너비가 부모 너비를 넘어서 늘어난다.

자동 확대 테이블에 width: 100%를 지정하면 가로 확대 절대 요소에 width: 100%를 지정했을 때와 거의 비슷하게 적용된다. 테이블에 테두리나 패딩을 지정할 경우, 테이블의 외부 박스는 늘어나지 않으며 테이블은 부모 요소 밖으로 넘치지 않는다.

테두리와 패딩이 테이블 내부에 렌더링되므로 외부 박스가 늘어나지 않기 때문이다. 한편, 테이블에 마진을 지정하면 테이블의 배치가 바뀌어 부모 요소 밖으로 넘친다.

*.box     { border:1px solid black; background-color:gold; } 
*.sized   { width:100px; height:35px; position:absolute; }

*.static-inline-shrinkwrapped    { width:auto;  }

*.replaced-inline-shrinkwrapped  { width:auto;  }
*.replaced-inline-sized          { width:35px;  }
*.replaced-inline-stretched      { width:100%; height:100%; }

*.static-block-sized             { width:300px; }
*.static-block-stretched         { width:auto;  }

*.table-shrinkwrapped            { width:auto;  }
*.table-sized                    { width:300px; }
*.table-stretched                { width:100%;  }

*.float-shrinkwrapped            { width:auto;  float:left;               }
*.float-sized                    { width:300px; float:left;   clear:both; }
*.float-stretched                { width:100%;  float:left;   clear:both; }

*.absolute-shrinkwrapped   { width:auto;  left:0; right:auto; position:absolute; top:370px; }
*.absolute-sized           { width:300px; left:0; right:auto; position:absolute; top:394px; }
*.absolute-stretched       { width:auto;  left:0; right:0;    position:absolute; top:418px; }
<span class="static-inline-shrinkwrapped box">정적, 인라인, 자동 축소<br>요소</span>

<img class="replaced-inline-shrinkwrapped box" src="star.png" alt="">
<img class="replaced-inline-sized box" src="star.png" alt="">
<span class="sized">
  <img class="replaced-inline-stretched box" src="star.png" alt="">
</span>

<div class="static-block-sized box">정적, 블록, 지정 크기</div>
<div class="static-block-stretched box">정적, 블록, 자동 확대, auto</div>

<table class="table-shrinkwrapped box"><tbody><tr><td>테이블, 자동 축소</td></tr></tbody></table>
<table class="table-sized box"><tbody><tr><td>테이블, 지정 크기</td></tr></tbody></table>
<table class="table-stretched box"><tbody><tr><td>테이블, 자동 확대, 100%</td></tr></tbody></table>

<span class="float-shrinkwrapped box">플로트, 자동 축소</span>
<span class="float-sized box">플로트, 지정 크기</span>
<span class="float-stretched box">플로트, 자동 확대, 100%</span>

<span class="absolute-shrinkwrapped box">절대, 자동 축소</span>
<span class="absolute-sized box">절대, 지정 크기</span>
<span class="absolute-stretched box">절대, 자동 확대, auto</span>

박스 모델 높이

height 속성은 인라인 요소를 제외한 모든 요소에 적용 가능한데 요소에 따라 다르게 적용하며, 배치를 지정했는지 플로트를 지정했는지에 따라서도 달리 적용된다. width 속성과는 완전히 별개이며 기본값은 height: auto이다.

  • height: auto : top: auto, bottom: auto, height: auto일때, 모든 박스 모델에서 높이가 자동 축소된다. 절대 위치 박스에 height: auto를 지정하고 top과 bottom 속성에 상수를 지정하면 세로로 늘어난다. height: 100%는 몇 가지 한계가 있으므로 박스를 세로로 늘이는 데는 height: auto가 최선이긴 하지만 절대 박스에만 사용할 수 있다.
  • height: 지정크기 : 고정 높이는 사용자 화면을 고려하여 지정하고 화면에 비례하여 보다 유연하게 표시되게 하려면 백분율을 사용하도록 한다.
  • height: 100% : height: 100%를 지정하면 페이지를 처음 로딩할 때는 요소의 높이가 부모 요소의 높이에 맞춰 늘어난다. 요소에 세로 마진, 테두리, 패딩을 지정하면 부모 요소의 높이보다 크게 늘어난다.

height: 100%를 지정한 자동 확대 테이블은 절대 위치 요소와 거의 비슷하게 표시된다. 테이블에 테두리나 패딩을 지정해도 외부 박스는 늘어나지 않으므로 부모 요소를 넘치지 않는다.

테이블의 외부 박스가 늘어나지 않는 이유는 테두리와 패딩이 테이블 내부에 렌더링되기 때문이다. 반면 자동 확대 테이블에 마진을 지정하면 배치가 바뀌어 부모 요소 밖으로 넘친다.

#div1 { position:absolute; top:50px;  left:20px; }
#div2 { position:absolute; top:145px; left:20px; }
#div3 { position:absolute; top:240px; left:20px; }
#div4 { position:absolute; top:335px; left:20px; }
#div5 { position:absolute; top:430px; left:20px; }

*.s1  { float:left; height:100%; width:155px; }
*.s2  { float:left; height:100%; width:105px; margin-left:35px;}
*.s3  { float:left; height:100%; width:105px; margin-left:35px;}

*.parent   { height:80px; width:435px; text-align:center; margin-top:5px; background-color:white; padding:0 134px; border:1px solid black; repeat-y; }
*.box     { background-color:gold; border:1px solid black; 1margin:5px; 1padding:5px;  } 

*.replaced-inline-shrinkwrapped  { height:auto;  }
*.replaced-inline-sized          { height:65px;  }
*.replaced-inline-stretched      { height:100%;  }

*.block-shrinkwrapped            { height:auto;   width:150px; }
*.block-sized                    { height:65px;   width:100px; }
*.block-stretched                { height:100%;   width:100px; }

*.table-shrinkwrapped            { height:auto;   width:150px; }
*.table-sized                    { height:65px;   width:100px; }
*.table-stretched                { height:100%;   width:100px; }

*.float-shrinkwrapped            { height:auto;   float:left;  width:150px;  }
*.float-sized                    { height:65px;   float:left;  width:100px;  margin-left:38px; }
*.float-stretched                { height:100%;   float:left;  width:100px;  margin-left:38px; }

*.absolute-shrinkwrapped   { height:auto;  top:0; bottom:auto; position:absolute; width:150px; left:135px; top:0px; }
*.absolute-sized           { height:65px;  top:0; bottom:auto; position:absolute; width:100px;  left:323px; top:0px; }
*.absolute-stretched       { height:auto;  top:0; bottom:0;    position:absolute; width:100px; left:463px; top:0px; }
<div id="div1" class="parent">
    <div class="s1">
        <img class="replaced-inline-shrinkwrapped box" src="star.png" alt="star">
    </div>
    <div class="s2">
        <img class="replaced-inline-sized box" src="star.png" alt="star">
    </div>
    <div class="s3">
        <img class="replaced-inline-stretched box" src="star.png" alt="star">
    </div> 
</div>

<div id="div2" class="parent">
    <div class="s1">
        <div class="block-shrinkwrapped box">블록<br>자동 축소</div>
    </div>
    <div class="s2">
        <div class="block-sized box">블록<br>지정 크기</div>
    </div>
    <div class="s3">
        <div class="block-stretched box">블록<br>자동 확대<br>100%</div>
    </div>  
</div>

<div id="div3" class="parent">
    <div class="s1">
        <table class="table-shrinkwrapped box"><tbody><tr><td>테이블<br>자동 축소</td></tr></tbody></table>
    </div>
    <div class="s2">
        <table class="table-sized box"><tbody><tr><td>테이블<br>지정 크기</td></tr></tbody></table>
    </div>
    <div class="s3">
        <table class="table-stretched box"><tbody><tr><td>테이블<br>자동 확대 100%</td></tr></tbody></table>
    </div>  
</div>

<div id="div4" class="parent">
    <span class="float-shrinkwrapped box">플로트<br>자동 축소</span>
    <span class="float-sized box">플로트<br>지정 크기</span>
    <span class="float-stretched box">플로트<br>자동 확대<br>100%</span>
</div>

<div id="div5" class="parent">
    <span class="absolute-shrinkwrapped box">절대<br>자동 축소</span>
    <span class="absolute-sized box">절대<br>지정 크기</span>
    <span class="absolute-stretched box">절대<br>자동 확대<br>auto</span>
</div>

박스 모델 지정크기

정적 배치된 인라인 요소를 제외한 모든 요소에 사용 가능하다.

  • width, height : 적당한 수치 값이나 부모 요소에 백분율을 지정한다. width와 height 속성은 요소의 내부 박스 크기를 설정한다. 내부 박스 둘레에는 패딩이 있고, 패딩 둘레에는 테두리가 있고, 테두리 둘레에 마진이 있다. 마진 둘레의 박스가 바로 외부 박스다. 패딩, 테두리, 마진으로 인해 외부 박스는 커지지만 내부 박스의 너비와 높이는 변하지 않는다. margin에 음수 값을 지정하면 인접한 요소가 겹칠 수도 있지만 너비와 높이는 변하지 않는다.
  • 테이블 요소 : 테이블은 예외적으로 width 속성과 height 속성이 테이블 테두리의 외부를 설정한다. 그래서 테두리와 패딩이 지정한 너비와 높이 안에 생긴다. 그림에서도 테이블이 나머지 요소보다 작은 것은 바로 이때문이다.
  • 플로트 요소 : 플로트 요소에 크기를 지정하면 흐름이 바뀐다. width 속성을 지정하면 플로트 요소의 내용이 흐르는 좌우 경계가 바뀌므로, 인접한 플로트 요소와 내용의 위치도 변한다. height 속성을 지정하면 인접한 플로트 요소가 밀리거나 당겨진다.
  • 정적 블록 요소 : 정적 블록 요소에 크기를 지정하면 흐름이 바뀐다. height 속성을 지정하면 뒤에 있는 블록 요소가 밀리거나 당겨진다. 그리고 height 속성을 지정하면 부모 요소에 크기를 지정하지 않았을 경우 부모 요소의 높이가 줄어들거나 늘어난다. width 속성을 지정하면 콘텐츠의 좌우 경계가 바뀐다.
  • 절대 위치 요소 : 절대 위치 요소에 크기를 지정해도 흐름에 영향이 없어서 다른 요소의 위치가 바뀌지 않는다. width와 height에 지정하는 백분율은 가장 가깝게 배치된 부모 요소의 너비와 높이를 기준으로 적용된다.
  • 대체 요소(img) : img 같은 대체 요소에 크기를 지정하면 브라우저는 이미지를 지정한 크기대로 표시한다. 원래의 이미지 크기로 표시되게 하려면 width와 height에 auto 값을 지정한다.
*.gp     { height:225px; position:relative; z-index:10; border:2px solid black; }
*.parent { margin:10px; padding:10px; padding-top:0; border:1px solid black;    }
*.z {padding:5px; border:5px solid black; background-color:gold; text-align:center;}

#float  { width:150px;  height:50px;  float:right;        }
#static { width:150px;  height:50px;  margin-bottom:10px; }
#table  { width:150px;  height:50px;  margin-bottom:10px; }
#abs    { width:150px;  height:50px; position:absolute; left:260px; margin-left:auto; right:auto; margin-right:auto; top:42px; margin-top:5px; bottom:auto; margin-bottom:auto; }
#star   { width:26px;   height:26px;  }
<div class="gp">배치된 부모의 부모 요소
    <div class="parent">배치되지 않은 부모 요소
        <div id="float" class="z">지정 크기 플로트 div</div>
        <div id="static" class="z">지정 크기 정적 배치 div</div>
        <table id="table" class="z"><tbody><tr><td>지정 크기 table</td></tr></tbody></table>
        <span id="abs" class="z">지정 크기 절대 위치 span
        <img id="star" src="star.png" alt="스타"></span>
    </div>
</div>

박스 모델 자동 축소

자동 축소 요소에는 반드시 width와 height 속성값을 auto로 지정해야 한다.

  • width, height : width: auto, height: auto처럼 너비와 높이를 자동으로 맞춘다. 둘 중 하나는 자동으로 맞춰지게 하고 다른 하나는 크기를 직접 지정 할 수도 있다.
  • 자동 축소 플로트 요소 : 선택자 { width:auto; height:auto; float:left 또는 right; }
  • 자동 축소 정적 배치 인라인 요소 : 인라인 선택자 { width:auto; height:auto; }
  • 자동 축소 정적 배치 인라인 블록 요소 : 인라인 블록 선택자 { width:auto; height:auto; }
  • 세로 축소 정적 배치 블록 요소 : 블록 선택자 { height:auto; }
  • 자동 축소 테이블 요소 : 테이블 선택자 { width:auto; height:auto; }
  • 가로 축소 절대 위치 요소 : 선택자 { position:absolute; width:auto; left:0; right:auto; } 또는 선택자 { position:absolute; width:auto; left:auto; right:0; }
  • 세로 축소 절대 위치 요소 : 선택자 { position:absolute; height:auto; top:0; bottom:auto; } 또는 선택자 { position:absolute; height:auto; top:auto; bottom:0; }

자동 축소 테이블은 안의 내용에 맞춰 크기가 조절되므로 원리는 다른 자동 축소 요소와 같다. 이것은 너비와 높이가 테이블 테두리 외부에 적용되어 다른 요소와 크기가 달라지는 지정 크기 테이블과는 대조적이다. 블록 요소의 크기를 제한하는 또 다른 방법은 max-height 속성과 max-width 속성을 지정하는 것이다.

IE6과 7은 자동 축소 테이블이 body 요소 이외의 요소 하위에 들어 있으면 margin-left 속성을 인식하지 않는 버그가 있다.

*.gp     { height:240px; position:relative; z-index:10; border:2px solid black;    }
*.parent { margin:10px; padding:10px; padding-top:0; border:1px solid black;       }
*.z {padding:5px; border:5px solid black; background-color:gold; text-align:center;}

#float  { width:auto;  height:auto;        margin-top:25px; float:left; }
#inline { width:auto;  height:auto;        margin-left:0; }
#star   { width:auto;  height:auto;        margin-left:115px; margin-top:10px;   }
#block  { width:auto;  height:auto;        margin-top:40px; }
#table  { width:auto;  height:auto;        margin-left:215px; margin-top:10px; }
#abs    { width:auto;  height:auto; position:absolute; left:auto; margin-left:auto; right:0; margin-right:20px; top:0; margin-top:70px; bottom:auto; margin-bottom:5px;  }
<div class="gp">배치된 부모의 부모 요소
    <div class="parent">배치되지 않은 부모 요소
        <span id="float" class="z">자동 축소 플로트 span</span>
        <span id="inline" class="z">자동 축소 정적 배치 인라인 span</span><br>
        <img id="star" src="star.png" alt="스타">
        <div id="block" class="z">세로 축소 정적 배치 블록 div</div>
        <table id="table" class="z"><tbody><tr><td>자동 축소 table</td></tr></tbody></table>
        <span id="abs" class="z">자동 축소 절대 위치 span</span>
    </div>
</div>

박스 모델 자동 확대

박스가 자동으로 늘어나게 하려면 width나 height에 auto나 100%를 적용한다. width: autoheight: auto를 지정하면 부모 요소의 너비/높이를 기준으로 자동 확대 요소의 너비와 높이를 설정한다.

브라우저는 요소 내부 박스의 너비와 높이를 계산할 때 부모 요소의 내부 박스에서 자동 확대 요소의 마진, 테두리, 패딩을 뺀다. 이는 자식 요소에 따라 부모 요소의 크기가 달라지는 지정크기/자동 축소 요소와 다르다.

  • width: auto : 요소의 너비가 부모 요소의 가장자리까지 늘어난다.
  • width: auto, left: 0, right: 0 : 절대 요소의 너비가 기준 요소의 좌우 가장자리까지 늘어난다.
  • height: auto, top: 0, bottom: 0 : 절대 요소의 너비가 기준 요소의 위/아래 가장자리까지 늘어난다.
  • width: 100% : 테이블, 플로트, 인라인 박스의 너비가 자동 확대된다. 이때 박스에 가로 마진을 지정하지 말아야 한다. 가로 마진을 지정하면 박스가 부모 요소를 넘쳐서 자동 확대 효과가 없어진다. 자동 확대를 적용한 플로트, 인라인 블록 박스에 border나 padding을 지정하면 부모 요소를 넘친다.
  • height: 100% : 인라인 블록, 블록, 테이블, 플로트 박스의 높이가 부모 요소의 높이에 맞춰 자동 확대 된다. 앞에 다른 자동 확대 요소가 있고 부모 요소 안의 유일한 자식이 아닐 때는 이 속성을 지정하면 박스가 부모 요소 밖으로 넘친다.
  • 자동 확대 인라인 블록 요소 : 인라인 블록 선택자 { width:100%; height:100% }
  • 자동 확대 정적 블록 요소 : 블록 선택자 { width:auto; height:100% }
  • 자동 확대 테이블 : 테이블 선택자 { width:100%; height:100% }
  • 세로 확대 절대 요소 : 선택자 { height:auto; top:0; bottom:0; position:absolute; }
  • 가로 확대 절대 요소 : 선택자 { width:auto; left:0; right:0; position:absolute; }
  • 자동 확대 플로트 요소 : 선택자 { width:100%; height:100%; float:left 또는 right; }

IE6 이하 버전은 자동 확대 절대 요소를 지원하지 않는다. 절대 위치 테이블을 자동 확대시키려면 width:100%와 height:100%를 지정한다.

*.gp     { height:340px; position:relative; z-index:10; border:2px solid black;    }
*.parent { height:280px; margin:10px 20px; padding:10px 0; padding-top:0; border:1px solid black;     }
*.s {padding:5px; border:5px solid black; background-color:gold; text-align:center;}

#sized  { width:50px;  height:50px;         margin:10px auto;}

#inline { }
#star   { width:100%;  height:100%; }
#block  { width:auto;               }
#table  { width:100%;                       margin:10px 0; }

#abs-v  { height:auto; top:0; bottom:0; position:absolute; width:120px; left:auto; margin-left:auto; right:0; margin-right:40px; top:0; margin-top:0; bottom:0; margin-bottom:0; }         
#abs-h  { width:auto; left:0; right:0; position:absolute; height:auto; left:0; margin-left:0; right:0; margin-right:0; top:auto; margin-top:0; bottom:auto; margin-bottom:auto; }

#float { width:100%; float:left; margin-top:50px; }
<div class="gp">배치된 부모의 부모 요소
    <div class="parent">배치되지 않은 부모 요소
        <span id="inline" class="s">확대 불가 정적 인라인 span</span>
        <div id="sized"><img id="star" src="star.png" alt="스타"></div>
        <div id="block" class="s">가로 확대 정적 배치 블록 div</div>
        <table id="table" class="s"><tbody><tr><td>가로 확대 table</td></tr></tbody></table>
        <div id="abs-v" class="s">세로 확대 절대 위치 div</div>
        <span id="abs-h" class="s">가로 확대 절대 위치 span</span>
        <span id="float" class="s">완전히 확대되지 않은 플로트 span</span>
    </div>
</div>

박스 모델 내부 박스

마진, 테두리, 패딩을 컨테이너에 지정하지 말고 콘텐츠 요소(내부 요소)에 지정한다. 이렇게 하면 컨테이너에는 마진, 테두리, 패딩이 없으므로 외부 너비가 내부 너비와 같고, 따라서 width 속성으로 콘텐츠의 외부 너비를 지정하는 효과가 있다.

width 속성은 요소의 내부 너비에 적용되며 마진, 테두리, 패딩은 요소의 외부 너비를 늘인다.

내부 박스 정의

마진, 테두리, 패딩을 박스 바깥에서 안으로 옮겼다는 뜻에서, 콘텐츠 요소를 내부 박스라고 부른다.

  • 내부 박스는 마진, 테두리, 패딩이 부모 요소 안에서 들여넣기되도록 반드시 부모 요소의 너비와 높이에 맞춰 자동 확대해야 한다.
  • 음수 마진을 사용해서 내부 박스를 내어쓸 수도 있다.
  • 블록 요소나 블록처럼 표시되는 인라인 요소는 브라우저가 기본적으로 자동 확대를 적용하므로 내부 박스를 만들기엔 안성맞춤이다.

내부 박스 적용법

outside-in box(oi), 콘텐츠 박스 하나만으로는 원하는 표현을 할 수 없을 때 컨테이너를 함께 쓰는 패턴이므로 내부 박스라고 한다.

<블록><div class="oi">내용</div></블록> 또는 <인라인><span class="oi"></span></인라인>

CSS 명세에 따르면, 브라우저는 테두리에 지정한 백분율을 무시한다고 돼 있다. 즉, 테두리에는 고정 수치를 지정해야 한다는 뜻이다. 마진과 패딩은 주로 표시영역을 조절하지 않아야 더 보기가 좋기 때문에 마진과 패딩에 백분율을 지정하는 일은 흔치 않다.

/* Non-essential Styles */
h2    { margin:0; margin-top:20px; font-size:1.1em; font-style:italic; }
h3    { margin:0; font-size:1em; }

.float-divider { clear:both; display:block; 
                  height:1px; font-size:1px; line-height:1px; }

.container    { width:125px; height:60px; float:left; position:relative; 
                 margin-right:75px; border:1px solid black; }

.before,.oi  { background-color:gold; }


/* Essential Styles */

.before       { width:100%; margin:5px; padding:5px; border:5px solid black; }

.after        { width:100%; }
.after   .oi { margin:5px; padding:5px; border:5px solid black; display:block; }

.float    { float:left;        }
.absolute { position:absolute; }
.static   { position:static;   }

<h2>Before</h2>
<div class="container">
    <div class="before float"> 플로트 띄움 </div>
</div>

<div class="container">
    <span class="before absolute"> 절대 배치 </span>
</div>

<div class="container">
    <div class="before static"> 정적 배치 </div>
</div>

<div class="float-divider"></div>

<h2>After</h2>
<div class="container">
    <div class="after float">
        <div class="oi"> 플로트 띄움 </div>
    </div>
</div>

<div class="container">
    <span class="after absolute"><span class="oi"> 절대 배치 </span></span>
</div>

<div class="container">
    <div class="after static">
        <div class="oi"> 정적 배치 </div>
    </div>
</div>