widthプロパティの説明
CSSのwidth
プロパティは、要素の幅を指定します。本プロパティで扱う幅は、CSSのボックス・モデルにおけるボックスの水平方向の寸法を表します。
width
が示す幅の基準を変えるには、box-sizing
を使用します。多くの場合、要素が作成するボックスの幅に合わせるため、HTML文書全体に対してborder-box
の値を適用します。
要素の最大幅はmax-width
、最小幅はmin-width
で個別に管理できます。また、要素の垂直方向の寸法、すなわち高さはheight
で操作します。
widthに指定できる値
auto
- ブラウザの自動計算に従います。これが初期値です。
<length>
- CSSで使用できる長さを表す単位付きの数値です。画面サイズや親要素の幅に影響されない絶対的な寸法を指定できます。
<percentage>
- 親要素の包含ブロックの幅に対する割合です。親要素の幅や画面のサイズが変わる環境で有用です。
max-content
- コンテンツが要求する最大の幅で表示します。
min-content
- コンテンツが要求する最小の幅で表示します。
fit-content(<length-percentage>)
- 利用可能な空間に対して
fit-content
の計算式を用いて、指定された引数に置き換えます。これは min(max-content, max(min-content, <length-percentage>)) と同じ結果を表します。
widthの使い方とサンプルコード
width
プロパティの構文は以下の通りです。
/* <length>値 */
width: 120px;
width: 16rem;
width: 5vmax;
/* <percentage>値 */
width: 25%;
width: 100%;
/* キーワード値 */
width: auto;
width: max-content;
width: min-content;
width: fit-content(10em);
/* グローバル値 */
width: inherit;
width: initial;
width: revert;
width: unset;
widthの実例
それでは実際にwidth
プロパティの書き方を見ていきましょう。まず初めに、要素の幅の基準となる場所を確認します。要素の幅は、ボックス・モデルにおけるコンテンツ・エリアを基準に表示されます。コンテンツ・エリアは、境界線の太さや余白の寸法を抜いた領域で、純粋にテキストや子要素が収まる範囲のことです。
コンテンツ・エリアを基準にすると、要素に境界線や内側の余白を指定した場合に、ボックスの寸法が膨張します。そのため、横に並べたボックスやピクセル単位で指定したレイアウトが崩れることがあります。
この現象を解決するためには、要素を入れ子にして親要素に幅を指定するか、box-sizing
プロパティを指定して、値をborder-box
にする必要があります。
<div class="samp_box">
<div id="item_1">
<span>box-sizing: content-box;</span>
<span>width: 300px;</span>
<span>padding: 10px;</span>
<span>border: 10px solid;</span>
</div>
<div id="item_2">
<span>box-sizing: border-box;</span>
<span>width: 300px;</span>
<span>padding: 10px;</span>
<span>border: 10px solid;</span>
</div>
</div>
.samp_box {
overflow: auto;
padding: 0 1rem 1rem;
background-color: #eee;
}
.samp_box > div {
width: 300px;
margin: 1rem auto 0;
padding: 10px;
border: 10px solid;
background-color: #fff;
font-size: 0.875rem;
}
div > span {
display: block;
}
#item_1 {
box-sizing: content-box;
}
#item_2 {
box-sizing: border-box;
}
要素の幅を正しく理解する
要素の幅について正しく理解するためには、ボックス・モデルの構成要素を分解してみることが近道です。以下の例では、padding
によって変わるパディング・エリアの範囲と、border
によって変わるボーダー・エリアの範囲を可視化しています。これらは、box-sizing
の値によって、外側へ向かって膨張するのか、内側へ向かって膨張しコンテンツ・エリアを圧迫するのかが変わります。
要素の寸法はwidth
の絶対値によって固定されています。それでも、二つのボックスの幅に違いが出るのは、幅の対象となる基準が異なるためです。実際にスライダーを動かして確認してみましょう。要素のコンテンツ・エリアの幅を基準にしたいのか、境界線の縁までを対象としてボックスの寸法を固定したいのか、実装する祭に最適な方を選べることが重要です。
<div id="samp_box">
<section id="controller">
<label>
<input type="range" step="1" min="0" max="30" id="i_width" disabled>
<span>width: 200px;</span>
</label>
<label>
<input type="range" step="1" min="0" max="30" id="i_padding">
<span id="msg_pad">padding</span>
</label>
<label>
<input type="range" step="1" min="1" max="30" id="i_border">
<span id="msg_bor">border</span>
</label>
</section>
<section id="view_1">
<h1>content-box</h1>
<div class="item" id="itemA">Content</div>
</section>
<section id="view_2">
<h1>border-box</h1>
<div class="item" id="itemB">Content</div>
</section>
</div>
<script>
const i_padding = document.getElementById('i_padding');
const msg_pad = document.getElementById('msg_pad');
i_padding.addEventListener('input', function() {
itemA.style.padding = i_padding.value + 'px';
itemB.style.padding = i_padding.value + 'px';
msg_pad.innerText = 'padding: ' + i_padding.value + 'px;';
}, false);
const i_border = document.getElementById('i_border');
const msg_bor = document.getElementById('msg_bor');
i_border.addEventListener('input', function() {
itemA.style.border = i_border.value + 'px solid #000';
itemB.style.border = i_border.value + 'px solid #000';
msg_bor.innerText = 'border: ' + i_border.value + 'px;';
}, false);
const itemA = document.getElementById('itemA');
const itemB = document.getElementById('itemB');
</script>
#samp_box {
overflow: auto;
padding: 0 1rem 1rem;
background-color: #eee;
}
#samp_box > section {
overflow: auto;
margin: 1rem 0 0;
padding: 0 1rem 1rem;
background-color: #fff;
}
#controller > label {
display: block;
padding: .3rem 0;
border-bottom: 1px solid #ccc;
}
#controller > label > input {
margin: 0 .3rem;
vertical-align: middle;
}
section > h1 {
margin: 1rem 0 0;
font-size: 1rem;
}
div.item {
width: 200px;
margin: 1rem auto 0;
padding: 5px;
border: 1px solid #000;
background-color: #09f;
background-clip: content-box;
color: #fff;
}
div > span {
display: block;
}
#itemA {
box-sizing: content-box;
}
#itemB {
box-sizing: border-box;
}
様々な幅の指定
width
の基本的な仕組みを覚えたら、後は具体的な幅を指定していくだけです。ここでは、単純なボックスに対して色々な値を付与して挙動を比較します。
一般的な制作過程では、レイアウトを優先してボックスの寸法を決めてしまい、コンテンツを流し込んでいくことが多いと思います。その場合は、<length>
値や<percentage>
値を使って具体的な数値を記述していくことになります。一方、コンテンツの寸法に合わせてボックスの大きさを変えたい場面などでは、キーワードのfit-content
が有効となります。
<div class="samp_box">
<div id="item_1">100px</div>
<div id="item_2">12em</div>
<div id="item_3">50%</div>
<div id="item_4">auto</div>
<div id="item_5">max-content</div>
<div id="item_6">min-content</div>
<div id="item_7">fit-content</div>
</div>
.samp_box {
overflow: auto;
padding: 0 1rem 1rem;
background-color: #eee;
}
.samp_box > div {
margin: 1rem 0 0;
padding: .5rem;
border: 1px solid #333;
background-color: #fff;
}
#item_1 {
width: 100px;
}
#item_2 {
width: 12em;
}
#item_3 {
width: 50%;
}
#item_4 {
width: auto;
}
#item_5 {
width: max-content;
}
#item_6 {
width: min-content;
}
#item_7 {
width: fit-content;
}