- CSS
CSS widthとheightの指定方法|100%が効かない原因と対処
CSSのwidthとheightとは、要素の横幅と高さを決めるプロパティで、初期値はどちらもauto(中身と親に合わせて自動で決まる)です。 px で固定するほか、%・vw・dvh のような相対指定、min-content・max-content・fit-content のような「中身基準」の指定、clamp() による上下限つきの指定ができます。
この記事では、使える値を挙動つきの一覧表にまとめ、「height: 100% が効かない」「width を書いたのに変わらない」といったつまずきを原因別に、再現コードと修正コードの対で並べました。数値はすべて Chromium 141(Playwright 1.56 のヘッドレス実行、ビューポート 1000×800px)で getBoundingClientRect() を使って測ったものです。スマホで 100vh がはみ出す件と dvh・svh の使い分けも最後に整理します。
widthとheightの早見表
親の幅が 600px、ビューポートが 1000×800px、文字は 16px のときの実測値です。
| 値 | 意味 | widthの実測 | heightでの挙動 | 主な用途 |
|---|---|---|---|---|
auto |
初期値。ブロックは親いっぱい、高さは中身ぶん | 600px | 中身の高さ(1行で24px) | 基本はこれで足りる |
300px |
固定の長さ | 300px | その高さで固定 | アイコン、固定サイズの枠 |
20em |
その要素の文字サイズ×20 | 320px | 同じ計算 | 文字量に合わせた幅 |
50% |
親(包含ブロック)の幅の50% | 300px | 親の高さが決まっているときだけ効く | カラム分割 |
50vw |
ビューポート幅の50% | 500px | 50vh は画面高の50% |
画面基準の配置 |
100dvh |
いま見えている画面の高さ | (高さ用) | 800px | 全画面セクション |
min-content |
折り返せるだけ折り返した最小幅 | 58.17px | 中身の高さと同じ | 最長の単語に合わせる |
max-content |
折り返さない幅 | 189.58px | 中身の高さと同じ | 1行に収めたいラベル |
fit-content |
中身ぶん。ただし親の幅を上限にする | 189.58px(長文は600px) | 中身の高さと同じ | 中身ぶんの幅で中央寄せ |
clamp(200px, 50%, 400px) |
下限・推奨・上限をまとめて指定 | 300px | 同じ書き方で指定可 | 伸び縮みする幅 |
calc(100% - 40px) |
計算で決める | 560px | 同じ書き方で指定可 | 余白を引いた幅 |
stretch |
親の空きをちょうど埋める(marginを含めて計算) | 600px | 親の高さが決まっていれば埋める | margin付きで親いっぱい |
まず覚えておきたいのは「widthの%はたいてい効くが、heightの%は親の高さが決まっていないと効かない」という非対称さです。 以降の「効かない」の多くはここから説明できます。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「CSS widthとheightの指定方法|100%が効かない原因と対処」
検証に使った環境と測り方
| 項目 | 内容 |
|---|---|
| ブラウザ | Chromium 141.0.7390.37(ヘッドレス) |
| 実行 | Playwright 1.56.0(Python) |
| ビューポート | 1000×800px |
| 共通CSS | * { margin: 0 }、body { font: 16px/1.5 'DejaVu Sans' } |
| 測り方 | getBoundingClientRect() の width/height を読む |
手元のブラウザで同じ数値を確かめたいときは、次のHTMLを保存して開き、開発者ツールのコンソールを見てください。フォントが違うと min-content などの中身基準の値は変わります。
<!doctype html>
<meta charset="utf-8">
<style>
* { margin: 0; }
body { font: 16px/1.5 sans-serif; }
.parent { width: 600px; }
.child { background: #ddd; }
</style>
<div class="parent"><div class="child" style="width: auto">Hello CSS width sample</div></div>
<div class="parent"><div class="child" style="width: 50%">Hello CSS width sample</div></div>
<div class="parent"><div class="child" style="width: min-content">Hello CSS width sample</div></div>
<div class="parent"><div class="child" style="width: max-content">Hello CSS width sample</div></div>
<div class="parent"><div class="child" style="width: fit-content">Hello CSS width sample</div></div>
<div class="parent"><div class="child" style="width: clamp(200px, 50%, 400px)">Hello CSS width sample</div></div>
<script>
document.querySelectorAll('.child').forEach(el => {
const r = el.getBoundingClientRect();
console.log(el.style.width, '=>', r.width, 'x', r.height);
});
</script>
widthとheightの基本
書き方
.box {
width: 300px; /* 横幅 */
height: 200px; /* 高さ */
}
指定しないときは auto で、ブロック要素(div・p など)は横幅が親いっぱい、高さは中身ぶんになります。 そのため、文章を入れる箱には height を書かず、中身に任せるのが扱いやすい形です。高さを固定すると、文字が増えたときに箱からあふれます。
width: auto と width: 100% の違い
どちらも「親いっぱい」に見えますが、auto は margin・padding・border を含めて親に収まり、100% は中身の領域だけで親の幅を使い切ります。 違いは padding を付けたときに出ます(後述の「原因3」で実測)。
| 指定 | padding 20px+border 1px を付けたとき(親600px) |
|---|---|
width: auto |
全体で600pxに収まる(中身は558px) |
width: 100% |
中身が600pxになり、全体は642pxで親からはみ出す |
width: 100% + box-sizing: border-box |
全体で600pxに収まる |
対になるプロパティ
| プロパティ | 役割 | 初期値 |
|---|---|---|
width / height |
基準になる大きさ | auto |
min-width / min-height |
これより小さくならない | auto(ブロックでは0として扱われる) |
max-width / max-height |
これより大きくならない | none |
inline-size / block-size |
書字方向に合わせた幅・高さ(横書きでは width / height と同じ) | auto |
aspect-ratio |
縦横比。片方が auto のときに効く |
auto |
box-sizing |
width・height に padding と border を含めるか | content-box |
値ごとの挙動を実測する
widthに使える値
親 .p { width: 600px } の中に、テキスト「Hello CSS width sample」を入れた div を置いて測りました。
<div class="p"><div style="width: fit-content">Hello CSS width sample</div></div>
実行結果(Chromium 141):
width: auto => 600
width: 50% => 300
width: 50vw => 500
width: 300px => 300
width: 20em => 320
width: min-content => 58.17
width: max-content => 189.58
width: fit-content => 189.58
width: clamp(200px, 50%, 400px) => 300
width: calc(100% - 40px) => 560
width: stretch => 600
同じ fit-content と max-content でも、中身が長いときに差が出ます。 「long text 」を20回くり返した文で測ると次のとおりです。
width: fit-content (長文) => 600 ← 親の幅で止まり、中で折り返す
width: max-content (長文) => 1520.55 ← 折り返さず、親からはみ出す
| 値 | 短い文 | 長い文 | 覚え方 |
|---|---|---|---|
min-content |
58.17px(最長の単語の幅) | 最長の単語の幅 | できるだけ細く |
max-content |
189.58px | 1520.55px(はみ出す) | 折り返さない |
fit-content |
189.58px | 600px(親で止まる) | 中身ぶん、ただし親まで |
迷ったら fit-content を選ぶと、短い文では中身ぶん、長い文では親の幅に収まります。 ボタンやタグのように「中身の幅にしたいブロック」を中央に置くときは、width: fit-content; margin-inline: auto; の2行で済みます。
heightに使える値
親の高さが決まっていない場合(A)と、height: 300px の場合(B)で、1行のテキストを入れた子の高さを測りました。
指定 A: 親の高さ未指定 B: 親 height:300px
height: auto 24 24
height: 50% 24 150
height: 100% 24 300
height: 100vh 800 800
height: 100dvh 800 800
height: 100svh 800 800
height: 100lvh 800 800
height: min-content 24 24
height: max-content 24 24
height: fit-content 24 24
height: stretch 24 300
読み取れることは3つです。
%とstretchは、親の高さが決まっていないとautoと同じ(24px)になる。vh・dvh・svh・lvhは親に関係なく画面基準で決まる。min-content・max-content・fit-contentは、通常のブロックの高さではautoと同じ結果になる。
clamp・min・max で上下限をまとめて書く
.card {
/* 200px以上、400px以下、その間は親の50% */
width: clamp(200px, 50%, 400px);
}
.wrapper {
/* 親いっぱい。ただし400pxまで */
width: min(100%, 400px);
}
実測(親600px):
width: clamp(200px, 50%, 400px) => 300
width: min(100%, 400px) => 400
width: max(50%, 400px) => 400
width: min(100%, 400px) は width: 100%; max-width: 400px; と同じ結果になります。1行で書きたいときは min()、あとから上限だけ上書きしたいときは max-width に分けておくと扱いやすくなります。
「効かない」の原因と対処の一覧
| 症状 | 原因 | 対処 |
|---|---|---|
span や a に width・height を書いても変わらない |
inline要素には幅・高さが適用されない | display: inline-block(または block) |
height: 100% が中身の高さのまま |
親の高さが auto |
親に height を指定/min-height: 100dvh/flex・gridで伸ばす |
親に min-height を書いたのに子の height: 100% が効かない |
min-height は % の基準にならない |
親を display: flex か grid にして伸ばす |
width: 100% にしたら親からはみ出す |
padding と border が外側に足される | box-sizing: border-box |
flexの子の width が指定より小さい |
flex-shrink: 1 で縮んでいる |
flex-shrink: 0、または flex-wrap: wrap |
| flexの子が長い文字で親からはみ出す | flexの子の min-width: auto が中身の幅を守る |
min-width: 0 |
gridの 1fr が均等にならない |
1fr は minmax(auto, 1fr) として働く |
minmax(0, 1fr) |
max-width を書いたのに広がる |
min-width のほうが大きい |
min・maxの優先順位を見直す |
| 画像が縦に伸びる | HTMLの height 属性が残っている |
height: auto を足す |
スマホで 100vh の下が切れる |
vh はアドレスバーが隠れた状態の高さ |
100dvh か 100svh |
以下、原因ごとに再現と修正を見ていきます。
原因1:inline要素に指定している
span・a・strong などは初期状態が display: inline で、inline要素には width と height が適用されません。
再現コード:
<style>
.tag { width: 200px; height: 100px; background: #ddd; }
</style>
<span class="tag">inline</span>
修正コード:
<style>
.tag { display: inline-block; width: 200px; height: 100px; background: #ddd; }
</style>
<span class="tag">inline-block</span>
実測:
span (display: inline) => 43.47 x 19 ← 文字ぶんの大きさのまま
span (display: inline-block) => 200 x 100
a (display: block) => 200 x 100
開発者ツールの「計算済み」欄には width: 200px と表示されますが、描画される箱は 43.47px のままでした。計算済みの値だけを見て「効いている」と判断せず、要素にカーソルを当てて実際の箱の大きさを見るのが確実です。
| やりたいこと | 選ぶ display |
|---|---|
| 文中に置いたまま幅・高さを付けたい | inline-block |
| 1行を占有させたい(リンク全体を押せるようにする等) | block |
| 中身を並べたい | inline-flex/flex |
img・input・button などは inline でも幅と高さを指定できます(置換要素やフォーム部品は例外です)。
原因2:height: 100% の親に高さがない
height の % は「親の高さが明示されているとき」だけ計算されます。 親が auto だと「親の高さは子で決まり、子の高さは親で決まる」という循環になるため、% は auto として扱われます。
再現コード:
<div class="parent">
<div class="child" style="height: 100%">A</div>
</div>
親の条件を8通りに変えて、子の高さを測りました。
| # | 親の指定 | 子の指定 | 子の高さ |
|---|---|---|---|
| 1 | なし(auto) |
height: 100% |
24px(効かない) |
| 2 | height: 300px |
height: 100% |
300px |
| 3 | min-height: 300px |
height: 100% |
24px(効かない) |
| 4 | min-height: 300px; display: flex |
指定なし | 300px |
| 5 | min-height: 300px; display: grid |
指定なし | 300px |
| 6 | min-height: 300px; position: relative |
position: absolute; height: 100% |
300px |
| 7 | min-height: 300px; display: flex; flex-direction: column |
flex: 1 |
300px |
| 8 | 祖父 height: 300px、親は指定なし |
height: 100% |
24px(効かない) |
3番が見落としやすい点で、min-height は % の基準になりません。 一方で 4・5番のように親を flex か grid にすると、子は height を書かなくても親の高さまで伸びます(align-items の初期値 stretch の働きです)。8番は、間にはさまった親が auto だと連鎖が切れることを示しています。
画面いっぱいにしたいとき
html と body も「親」です。ここが auto のままだと、height: 100% は中身の高さになります。
html, body 指定なし + .box { height: 100% } => box 24 / html 24 / body 24
html, body { height: 100% } + .box { height: 100% } => box 800 / html 800 / body 800
.box { min-height: 100dvh } => box 800
修正コード(おすすめ):
.hero {
min-height: 100dvh; /* 親をさかのぼらずに画面の高さを使える */
}
画面の高さが欲しいだけなら、% を親から順につなぐより min-height: 100dvh の1行のほうが短く書けます。 height ではなく min-height にしておくと、中身が画面より長いときに箱が伸びてくれます。
修正方法の選び方
| 状況 | 向いている修正 |
|---|---|
| 親の高さが決まった数値でよい | 親に height を書く |
| 親は「最低この高さ」にしたい | 親を display: flex か grid にして子を伸ばす |
| 画面の高さに合わせたい | min-height: 100dvh |
| 残りの高さを全部使いたい(ヘッダーの下など) | 親を flex-direction: column にして子に flex: 1 |
| 親に重ねて全面を覆いたい | 親 position: relative、子 position: absolute; inset: 0 |
原因3:box-sizingでpaddingぶん大きくなる
初期値の box-sizing: content-box では、width と height は「中身の領域」だけの大きさで、padding と border はその外側に足されます。
再現コード:
<style>
.parent { width: 600px; }
.child { width: 100%; padding: 20px; border: 1px solid #333; }
</style>
<div class="parent"><div class="child">x</div></div>
修正コード:
.child { width: 100%; padding: 20px; border: 1px solid #333; box-sizing: border-box; }
実測:
content-box: 子の全体幅 642 / 親の scrollWidth 642 ← 42pxはみ出す
border-box : 子の全体幅 600 / 親の scrollWidth 600
計算は 600 + 20×2 + 1×2 = 642px です。多くのサイトでは、次のように全要素へまとめて指定しています。
*, *::before, *::after {
box-sizing: border-box;
}
これを最初に書いておくと、「指定した width = 見た目の幅」になり、計算がしやすくなります。
原因4:flex・gridの子になっている
flexの子が指定より縮む
flexの子は初期値が flex-shrink: 1 で、親に入りきらないときは width より縮みます。
再現コード:
<style>
.row { display: flex; width: 600px; }
.item { width: 300px; }
</style>
<div class="row">
<div class="item">1</div><div class="item">2</div><div class="item">3</div>
</div>
実測:
そのまま => 各 200px(300pxの指定が縮む)
.item { flex-shrink: 0 } => 各 300px(親の scrollWidth は 900 になり横にあふれる)
.row { flex-wrap: wrap } => 各 300px(2行に折り返し、親の高さ 48px)
| やりたいこと | 修正 |
|---|---|
| 幅を必ず守りたい(アイコン、サムネイル) | flex-shrink: 0(まとめて書くなら flex: 0 0 300px) |
| 入りきらないときは次の行へ送りたい | 親に flex-wrap: wrap |
| 残りを分け合いたい | flex: 1(width は書かない) |
flexの子が長い文字ではみ出す(min-width: 0)
flexの子は min-width の初期値 auto が「中身の最小幅より小さくならない」ように働きます。折り返さない長い文字が入ると、flex: 1 の子でも親を押し広げます。
再現コード:
<style>
.row { display: flex; width: 300px; gap: 8px; }
.icon { flex: 0 0 40px; }
.text { flex: 1; }
.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
</style>
<div class="row">
<div class="icon">I</div>
<div class="text"><p class="ellipsis">VeryLongFileName_2026_10_03_report_final_version_checked.xlsx</p></div>
</div>
修正コード:
.text { flex: 1; min-width: 0; }
実測:
min-width 指定なし => .text 530.75px / 親の scrollWidth 579 ← 300pxの親からはみ出し、省略記号も出ない
min-width: 0 => .text 252px / 親の scrollWidth 300 ← 収まり、末尾が…になる
「省略記号(…)が出ない」「flexの中だけ横スクロールが出る」ときは、まず flexの子に min-width: 0 を足してみてください。 縦方向(flex-direction: column)で同じことが起きたら min-height: 0 です。なお、flexの子自身に overflow: hidden が付いている場合は min-width が自動的に0として扱われるため、この問題は起きません(同じ条件で確認し、どちらも 252px でした)。
gridの1frが均等にならない
1fr は minmax(auto, 1fr) と同じ意味で、下限が中身の幅になります。
/* 再現:左の列に折り返さない長い文字があると均等にならない */
.grid { display: grid; width: 300px; grid-template-columns: 1fr 1fr; }
/* 修正:下限を0にする */
.grid { display: grid; width: 300px; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
実測:
1fr 1fr => 左 530.75px / 右 10.98px / 親の scrollWidth 542
minmax(0, 1fr) minmax(0, 1fr) => 左 150px / 右 150px
flexの子の高さ
flexの子は、高さを書かなくても親の高さまで伸びます。
親 { display: flex; height: 200px }
子(指定なし) => 200px(stretch)
子 { height: 50% } => 100px
子 { align-self: flex-start } => 24px(中身ぶん)
「flexにしたら子の高さがそろってしまった」ときは align-items: flex-start、「そろえたいのにそろわない」ときは子に height や align-self が付いていないかを確認します。
原因5:min・maxの優先順位
3つが食い違うときの強さは min-width > max-width > width です。 まず width を max-width で切り詰め、その結果を min-width で引き上げる、という順で決まります。
実測(親600px):
width:500px; max-width:300px => 300
width:500px; max-width:300px; min-width:400px => 400 ← minが勝つ
width:100%; max-width:400px => 400
width:100px; min-width:50% => 300
height:50px; min-height:100px => 高さ 100
height:500px; max-height:200px => 高さ 200
height:500px; max-height:200px; min-height:300px => 高さ 300 ← minが勝つ
| よく使う組み合わせ | 意味 |
|---|---|
width: 100%; max-width: 960px; |
基本は親いっぱい、広い画面では960pxで止める |
min-height: 200px;(height は書かない) |
最低200px、中身が増えたら伸びる |
max-height: 300px; overflow: auto; |
300pxを超えたら中でスクロール |
min-width: 0; |
flex・gridの子が縮めるようにする |
「max-width が効かない」ときは、同じ要素の min-width と、詳細度の高い別のルールで width や max-width が上書きされていないかを開発者ツールで確認します。
もう1つ、% の max-width は親の幅が中身で決まる場面(親が max-content や float、inline-block など)では基準が定まらず、期待どおりに計算されないことがあります。そのときは親に幅を与えるか、px や vw など親に依存しない単位にします。
画像のwidthとheight
幅800px・高さ400pxの画像を、幅600pxの親に入れて測りました。
<img>(CSSなし) => 800x400(親からはみ出す)
<img style="max-width:100%"> => 600x300
<img width="800" height="400" style="max-width:100%"> => 600x400(縦に伸びる)
<img width="800" height="400" style="max-width:100%; height:auto"> => 600x300
<img style="width:200px; height:200px"> => 200x200(比率が変わる)
HTMLに width・height 属性を書いたうえで、CSSは max-width: 100%; height: auto; にするのが定番です。 属性があると読み込み前から縦横比がわかり、画像が出た瞬間に下の文章がずれる現象を抑えられます。
img {
max-width: 100%;
height: auto;
}
比率を変えずに決まった枠へ収めたいときは object-fit: cover、枠の比率そのものを決めたいときは aspect-ratio を使います。
width:300px; aspect-ratio:16/9 => 300 x 168.75
width:300px; aspect-ratio:16/9; height:100px => 300 x 100 ← heightを書くとaspect-ratioは使われない
スマホで100vhがはみ出す問題とdvh・svh・lvh
スマホのブラウザは、スクロールに合わせてアドレスバーやツールバーが出たり隠れたりします。100vh は「バーが隠れた状態」の高さを指すため、バーが出ている間はそのぶん画面より長くなり、下端が隠れます。 MDN の length のページでも、vh などの既定のビューポート単位は現在のところ lvh などの large 系と同じ、と説明されています。
| 単位 | 基準 | バーが出ているとき | バーが隠れたとき | 向いている用途 |
|---|---|---|---|---|
100vh |
large と同じ | 画面より長い | ちょうど | 以前からある指定の互換用 |
100lvh |
バーが隠れた状態(最大) | 画面より長い | ちょうど | 背景など、多少長くてもよいもの |
100svh |
バーが出た状態(最小) | ちょうど | 下に少し空きが出る | 最初の画面に必ず収めたい内容 |
100dvh |
いまの表示状態に追従 | ちょうど | ちょうど | 全画面のメニュー、モーダル |
迷ったときの選び方は次のとおりです。
- 下端に置いたボタンを常に見せたい →
100dvh - スクロール中に高さが変わってほしくない(最初の画面のビジュアルなど) →
100svh - 対応状況に幅を持たせたい →
vhを先に書き、次の行でdvhを上書きする
.fullscreen-menu {
height: 100vh; /* dvh を解釈しないブラウザ向け */
height: 100dvh; /* 解釈できるブラウザはこちらが使われる */
}
.hero {
min-height: 100svh;
}
dvh はバーの出入りに合わせて値が変わるので、スクロール中に要素の高さも変わります。大きな見出しエリアで高さが動くのが気になる場合は svh が落ち着きます。
今回の検証環境(デスクトップのヘッドレス Chromium)にはアドレスバーの出入りがないため、4つの単位はすべて 800px で同じ値でした。スマホ実機でバーが出入りしたときの差は、この記事では未実行です。 上の表の説明は MDN の定義に沿って書いています。
100vwと縦スクロールバー
100vw はスクロールバーの幅を含むため、常時表示型のスクロールバーがある環境では width: 100vw の要素が少しだけはみ出し、横スクロールが出ることがあります。今回のヘッドレス環境はスクロールバーが幅を取らない設定で、100vw も 100% も 1000px となり再現しませんでした(未再現)。全幅にしたいだけなら width: 100%(ブロック要素なら指定なしの auto)のほうが環境に左右されません。
知っておくと便利な新しめの指定
Chromium 141 で CSS.supports() が true を返したものです。ほかのブラウザでの対応状況は今回確認していないので、使う前に確かめてください。
| 指定 | できること | Chromium 141 |
|---|---|---|
width: stretch / height: stretch |
margin を含めて親の空きをちょうど埋める | 対応 |
interpolate-size: allow-keywords |
height: 0 から auto へのアニメーション |
対応 |
field-sizing: content |
入力欄を入力内容に合わせて伸ばす | 対応 |
height: 100dvh/100svh/100lvh |
表示状態に応じた画面の高さ | 対応 |
stretch は実測でも width: stretch が 600px、親の高さが 300px のとき height: stretch が 300px になりました。親の高さが未指定のときは 24px で、% と同じく親の高さが必要です。
コピペで使える定番パターン
/* 1. 全体の初期設定 */
*, *::before, *::after { box-sizing: border-box; }
img, video { max-width: 100%; height: auto; }
/* 2. 中央寄せのコンテナ:基本は親いっぱい、最大960px */
.container {
width: min(100% - 32px, 960px); /* 左右に16pxずつ余白を残す */
margin-inline: auto;
}
/* 3. 中身ぶんの幅のボタンを中央に */
.button {
display: block;
width: fit-content;
margin-inline: auto;
padding: 12px 24px;
}
/* 4. 画面の高さを使う最初のセクション */
.hero { min-height: 100svh; }
/* 5. ヘッダー・本文・フッターを縦に並べ、本文が残りを使う */
body { min-height: 100dvh; display: flex; flex-direction: column; margin: 0; }
main { flex: 1; }
/* 6. flexの中で長い文字を…で省略 */
.row { display: flex; gap: 8px; }
.row > .text { flex: 1; min-width: 0; }
.row > .text > p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 7. 均等な2カラム(中身が長くても崩れない) */
.cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
/* 8. 高さに上限を付けて中でスクロール */
.list { max-height: 300px; overflow: auto; }
効かないときの確認チェックリスト
| 順番 | 確認すること | 見る場所 |
|---|---|---|
| 1 | その要素の display は inline ではないか |
開発者ツールの「計算済み」 |
| 2 | height が % なら、親に height があるか(min-height ではなく) |
親要素のスタイル |
| 3 | box-sizing は border-box か |
計算済み |
| 4 | 親が flex・grid ではないか。flex-shrink・min-width は適切か |
親要素の display |
| 5 | min-width・max-width・min-height・max-height が食い違っていないか |
計算済み |
| 6 | 別のルールで上書きされていないか(取り消し線が付いていないか) | スタイル欄 |
| 7 | 値の書き間違いはないか(単位なしの width: 300 は無効) |
スタイル欄の警告表示 |
1→5の順に見ると、今回取り上げた原因をひととおり確認できます。 7番について、0 以外の長さには単位が必要です。
よくある質問
Q. heightは書いたほうがよいですか?
A. 文章を入れる箱には書かず、auto に任せるのがおすすめです。高さを固定すると、文字が増えたり文字サイズが変わったりしたときに中身があふれます。最低限の高さが欲しいときは min-height を使うと、中身が増えたぶんだけ伸びてくれます。
Q. width: 100% と width: auto はどちらを使えばよいですか?
A. ブロック要素を親いっぱいにしたいだけなら、何も書かない(auto)で足ります。auto は margin を含めて親に収まるので、左右に margin を付けてもはみ出しません。100% が必要なのは、inline-block・画像・position: absolute の要素・flexの子など、auto では中身ぶんの幅になるものを広げたいときです。
Q. fit-content と max-content はどう使い分けますか?
A. 短い文ではどちらも同じ幅(実測 189.58px)になります。長い文になったとき、fit-content は親の幅(600px)で止まって折り返し、max-content は折り返さずに 1520.55px まで広がりました。親に収めたいなら fit-content、横スクロールの表のように折り返したくないときは max-content です。
Q. 100vh と 100% はどう違いますか?
A. 100vh は親に関係なく画面の高さ、100% は親の高さが基準です。100% は親の高さが決まっていないと効きませんが、vh や dvh はどこに書いても画面基準で決まります。スマホではバーの出入りを考えて dvh か svh を選ぶと下端が隠れにくくなります。
まとめ
- widthとheightの初期値は
auto。 ブロック要素の幅は親いっぱい、高さは中身ぶんになる。 - height の
%は親の高さが明示されているときだけ効く。min-heightは基準にならないので、親を flex・grid にするかmin-height: 100dvhを使う。 - inline要素には width・height が付かない。
display: inline-blockかblockに変える。 width: 100%+ padding ではみ出すときはbox-sizing: border-box。 実測で 642px が 600px に収まった。- flexの子は縮む(
flex-shrink)一方で、中身より小さくならない(min-width: auto)。 幅を守るならflex-shrink: 0、収めるならmin-width: 0。 - 強さは
min-width>max-width>width。 食い違ったら min が勝つ。 - スマホの全画面は
100dvh(追従)か100svh(最小に固定)。vhを先に書いて上書きすると対応の幅が広がる。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「CSS widthとheightの指定方法|100%が効かない原因と対処」
株式会社RJCでは、CSSのwidthとheightの指定方法を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。