ボックスモデルとは

今回から第二章です。第二章のタイトルは「ボックスモデル」ですので、まずボックスモデルとは何かということを解説します。

簡単に言うと、ボックスとは何かということです。ボックスとは何かを定義するのがボックスモデルであるといえます。つまり、ボックスモデルを理解するとは、ボックスを理解するということです。

ではボックスとは何かというと、簡単にいうと端から端まで占領する要素です。例えば次の例をみましょう。

<p style="background-color:#aaffff">段落</p>

段落

p要素にbackground-colorプロパティをつかって背景色をつけました。しかし、「段落」の二文字の部分だけでなく、やけに右のほうまで色がついていますね。これは、この部分までがp要素であるということを示しています。

といっても、画面の端から端までというわけではありませんね。結局はなんの端かというと、親ブロックの端から端までです。

親ブロックというのは、親であるブロックです。例えばp要素のほかにもdiv要素(六章で登場)もブロック要素です。次のようなHTMLを考えましょう。

<div>
  <p>段落</p>
</div>

「段落」というp要素は、親であるdiv要素の端から端までを占領しているというわけです。このサイトでは、説明部分の親ブロックは色がついてるこの部分というわけです。参考までに、親ブロックが画面の端から端までになるサンプルも用意しました。イメージを掴みましょう。

ちなみに、ブロックと対になるものとしてインラインというものがあります。これは、端から端まで占領しないものです。代表例はspan(六章で登場)です。インライン要素は、他にもstrong,aなどたくさんあります。ようするに文中に登場するような要素です。対してブロック要素はp要素(段落)やsection要素(セクション)というように、文中の何かというよりはもっとページの構造のような大きなものを表しています。

<p>段落<span style="background-color:#aaffff">の中の色付き部分</span>です。</p>

段落の中の色付き部分です。

ブロックになるHTML要素はブロック要素と呼ぶことがありますが、ブロック要素は端から端まで占領するので、次にきたブロック要素は下に入ります。インライン要素は、普通の文字が並ぶように右につながっていきます。

このページも、各段落はp要素をつかって書かれています。p要素で文章を区切ると、段落ごとに改行がはいって行間があきます。これは、p要素がブロック要素であり、p要素が上から下へ積み重なっているからなのです。

ブロックの大きさを指定する

ここでブロックモデルの基本となる、ブロックの大きさというものを指定してみましょう。widthプロパティ,heightプロパティを使います。

width

意味

ボックスの幅。

auto,長さまたはパーセンテージ。

デフォルト値

auto

autoは、自動で良い感じに決定してくれます。なぜかは次回説明しますが、上述のように端から端までになります。

長さの場合はボックスの長さです。パーセンテージは、親ボックスの横幅を基準にして何%かということです。

<div style="width:200px;background-color:red">ここはdivです</div>
ここはdivです

横幅が端から端までではなく、もっと狭い大きさになったことがわかると思います。

height

意味

ボックスの高さ。

auto,長さまたはパーセンテージ。

デフォルト値

auto

heightも使い方は同じですが、パーセンテージは注意する必要があります。widthが親ボックスの横幅基準なのでheightでは高さ基準かとおもいきや、heightでも親ボックスの横幅基準です

<div style="width:200px;height:200px;background-color:red">ここはdivです</div>
ここはdivです

正方形のボックスができました。ちなみに、widthで長さがautoの場合は前述のように端から端までになりましたが、heightの場合は違います。autoの場合は中身が全部入る最低限の高さになります。上のp要素に色をつけた例では、p要素の中身は文1行だったので、p要素の高さは文が1行入るだけの高さになっています。

マージン

ブロックはマージンを持ちます。マージンとは余白のことです。つまり、ブロックの周囲に隙間をあけた感じです。これは上下左右に100pxの余白がついたブロックの例です。

<div style="width:200px;height:200px;background-color:#aaffff;margin:100px">ここはdivです</div>
ここはdivです

なんとなく、ブロックの周囲が空いてますね。ブロックの周囲100pxをマージンとして、ブロックが占領しているからです。このように、ブロックが占領する範囲は、ブロック本体にマージンを含めた領域です。

ここで登場したmarginプロパティがブロックのマージンを決定しています。

実は、上下左右のマージンを個別に設定することができます。それぞれmargin-top,margin-bottom,margin-left,margin-rightです。例えば、ボックスを右にずらしたいときは、左にだけマージンを設定することでボックスの中身の位置を右に移動させることができます。

<div style="width:200px;height:100px;background-color:#aaffff;margin-left:100px">divの位置が右に100pxずれています</div>
divの位置が右に100pxずれています

margin-top, margin-bottom, margin-left, margin-right

意味

上下左右のマージンの長さ。

auto,長さまたはパーセンテージ。

デフォルト値

0

デフォルト値が0なので、特にマージンを決めなかった場合マージンは無しになるということですね。

さて、先に紹介したmarginプロパティは、margin-top,margin-bottom,margin-left,margin-rightの4つを一括で指定できるプロパティだったのです。つまり、marginプロパティを書くのと前述の4つのプロパティを1つずつ書くのは同じ意味になります。また、marginプロパティは4つを全部一括で指定する他にも使い道があります。

margin

意味

マージンを一括で指定する。

マージンの長さを1つ~4つスペースで区切って指定する。

上でみた例はマージンの長さを1つ指定した例でしたが、2つだけ指定する、3つ指定する、4つ全部指定するということも可能です。それぞれの動作を見てみましょう。

4つ全部指定した場合
margin-top,margin-right,margin-bottom,margin-leftの順に当てはめられます。

3つの場合
4つの場合からleftが省略されたと見なされ、margin-leftmargin-rightと同じになります。
つまり、1つ目がmargin-top、2つ目がmargin-rightmargin-left,3つ目がmargin-bottomになります。
2つの場合
3つの場合からさらにbottomが省略されたと見なされ、margin-bottommargin-topと同じになります。
つまり、1つ目がmargin-topmargin-bottom、2つ目がmargin-rightmargin-leftです。
1つの場合
4つ全部同じになります。
2つの場合からさらにmargin-rightが省略されてmargin-topと同じになったとみなすこともできますね。

これならmarginプロパティだけあれば事が足りるようにも思えますが、そうではありません。これは必ず4つ全部書き換えてしまうからです。次のように上書き指定したい場合は個別のプロパティが役に立ちます。

<style>
  section {
    /* とりあえずセクションはマージン8px */
    margin:8px;
  }
  section.important {
    /* importantクラスのある大事なセクションは右にずらしたいので左のマージンは30px */
    margin-left:30px;
  }
</style>

また、マージンにはマイナスの値を指定することもできます。例えばmargin-leftをマイナスにすると、普通より左の位置に飛び出します。

<div style="width:200px;height:100px;background-color:#aaffff;margin-left:-100px">divの位置が左に100pxずれています</div>
divの位置が左に100pxずれています

この方法の特徴は、親ボックスを飛び出すことができるということです。margin-topmargin-bottomでも似たようなことができますが、やると読みにくいのでここではしません。自分で試してみましょう。

widthとマージンの自動調整

勘の良い方ならあることに気づいたかもしれません。上で「ブロックが占領する範囲は、ブロック本体にマージンを含めた領域である」といいました。しかしそもそもブロック要素とは何だったかというと、端から端まで占領する要素でしたね。さっきの周り全部100pxの例を考えると、ブロック本体が200px占領して、左右100pxだから合計で横幅400pxの領域を占領していることになります。

しかし、親ブロックの横幅が400px以上あったら、端から端までではなくなってしまいます。これはブロック要素の定義に反してしまいます。そこで、そのような場合に調整が入ります。具体的にはどうするかというと、残り全部がmargin-rightに突っ込まれます。つまり、親ブロックの横幅が600pxあったとしたら、margin-rightには調整が入り、100pxではなく300pxと見なされていたのです。その結果、ブロックは左に寄った位置に落ち着いていたのです。このように、調整が入って何が何でもブロックは端から端まで占領するんだということは覚えておきましょう。

また、マージンには長さだけでなくautoを指定することが可能です。これも、調整に身を任せるということです。そのため、さっきの例ではmargin-right:autoとしても同じようになります。また、margin-left:autoとしてみたらどうなるでしょうか。

<div style="width:200px;height:200px;background-color:#aaffff;margin:50px;margin-left:auto">ここはdivです</div>
ここはdivです

こうすると、divが右に移動しましたね。まずこのように、marginプロパティを指定したあとにmargin-leftを上書きするというやり方もたまにします。margin:50px 50px 50px autoと同じ意味ですがこちらのほうがわかりやすい場合などがあります。

さて、今widthmargin-rightが既に決まっていますので、残りのマージンはmargin-leftが自由に調整していいことになっているのでそこに入ります。その結果このようになります。margin-rightは50pxですから、このdivは親ブロックの右端から50px左にずれたところに配置されます。

ちなみに、margin-top,margin-bottomというように、縦方向のマージンにautoと指定した場合は0として扱われます。

また、margin-leftmargin-rightが両方autoだった場合には、マージンが左右に均等に割り振られます。その結果ボックスは中央に移動します。

<div style="width:200px;height:200px;background-color:#aaffff;margin:auto">ここはdivです</div>
ここはdivです

margin:autoでは上下左右全部autoになりますが、前述のように上下は0として扱われます。上下にも別にマージンを付けたいならば、margin:50px autoなどとするとよいでしょう。このようにmargin:autoを使用してボックスを中央に寄せるのはよく見られる方法です。

パディング

さて、マージンの次はパディングを紹介します。マージンはボックスの外に隙間を空けるものでしたが、パディングはボックスの中に隙間を開けます。例を見てみましょう。

<div style="width:200px;height:200px;background-color:#aaffff;">パディング無しのdiv</div>
<div style="width:200px;height:200px;background-color:#ffaaff;padding:30px">パディング有りのdiv</div>
パディング無しのdiv
パディング有りのdiv

一目見て分かるのは、widthやheightが同じはずなのにボックスの大きさが違いますね。もう一つ違うのは、パディング無しだと文字がdivの左上にぴったりとくっついているのに、パディング有りだと30pxの隙間が上と左にあいています。

これでパディングの意味がなんとなく分かったのではないでしょうか。パディングは、ブロックの中身の周りに追加される隙間です。ただしマージンとは違い、そこもブロックの内部として扱われます。パディングは、文字がブロックの端にぴったりくっついてしまうと見にくい場合あるので少し離したりするのに使われます。

ここで登場したのがpaddingプロパティです。他にpadding-top,padding-right,padding-bottom,padding-leftもあって、上下左右のパディングを個別に設定できます。使い方はmarginと同様です。先ほどのpadding:30pxというコードは、上下左右のパディングを全部30pxに設定したのです。

padding-top, padding-bottom, padding-left, padding-right

意味

上下左右のパディングの長さ。

長さまたはパーセンテージ。

デフォルト値

0

padding

意味

パディングを一括で指定する。

パディングの長さを1つ~4つスペースで区切って指定する。

ちなみにパディングにはauutoはありませんので注意しましょう。また、2つのボックスで大きさが違ったことから分かるように、パディング部分はwidthやheightの指定に含まれません(ただし、次回紹介するbox-sizingを使うとこの挙動は変えられます)。

その他のプロパティ

他にもいくつか関係するプロパティがあるので紹介します。

まず、min-width,max-width,min-height,max-heightを紹介します。minとは最小値、maxとは最大値のことです。つまり、widthやheightを直接決めてしまうかわりに、最小値と最大値を決めて猶予をもたせることができるのです。

たとえばmin-heightの例を見てみましょう。

<div style="width:200px;background-color:#aaffff;min-height:1.5em">1行のdiv</div>
<div style="width:200px;background-color:#ffaaff;min-height:1.5em">これは長々と長いことが書いてあって下に伸びているdivです。2行以上になると高さが足りなくなってdivが伸びます</div>
1行のdiv
これは長々と長いことが書いてあって下に伸びているdivです。2行以上になると高さが足りなくなってdivが伸びます

この例では、2つのdivでCSSはまったく同じなのに高さが違っています。上で見たとおり、この場合heightが指定されていなくてデフォルトのauto扱いになるので上のdivは1行分の高さだけ確保しようとしますが、min-heightの制約があるので1.5em分だけ確保することになります。下のdivも同様に高さを計算すると、1行では足りなくてもっと長くなります。その結果min-heightの制約をクリアして、必要な長さ分だけ確保されます。

同様に、max-heightも使ってみましょう。

<div style="width:200px;background-color:#aaffff;max-height:2em">1行のdiv</div>
<div style="width:200px;background-color:#ffaaff;max-height:2em">これは長々と長いことが書いてあって下に伸びているdivです。限界に達するとボックスの外に文字がはみ出ます</div>
1行のdiv
これは長々と長いことが書いてあって下に伸びているdivです。限界に達するとボックスの外に文字がはみ出ます

このように、ボックスの外に文字がはみ出ます。

上のdivは普通どおり1行です。しかし下のdivではmax-heightに制限されて必要なだけの高さが確保されず、文字がはみ出てしまっています。

もちろん、minとmaxを組み合わせることも可能です。試してみましょう。

ただし、はみ出るのが格好悪い場合はスクロールバーを出したりさせることも可能です。これはのちのち紹介します。

visibility

最後にvisibilityプロパティを紹介します。

visibility

意味

ブロックを表示するかどうか。

visibleまたはhidedn

デフォルト値

visible

visibilityをhiddenにすると、表示されなくなります。ブロックがもともとあった場所は空白になり、詰められるわけではありません。詰めるには、今度紹介するdisplayプロパティを使います。

次回はさらにボックスをいじる方法を紹介します。

出典:CSS basic box model W3C Working Draft 9 August 2007