clientWidth / clientHeight とは何か
clientWidth と clientHeight は、要素の「内側で実際に使える領域」のサイズを整数ピクセルで返すプロパティです。ここが重要です:content(中身)+ padding を含み、border と内部スクロールバーは含みません。つまり「要素の中にレイアウトできるスペース」を知るための値で、テキストの折り返しやコンテンツの収まり判定、内側に要素を並べるときの基準に最適です。
何が含まれ、何が含まれないか(ボックスモデルの要点)
含まれるものと含まれないものの整理
clientWidth/Height は「content+padding」を返し、border(枠線)と内部スクロールバーの厚みは含みません。ここが重要です:offsetWidth/Height(外側の箱寸法。padding+border+スクロールバー込み)と役割が違います。内側のレイアウト計算は client、外側の位置合わせは offset を使うとズレが減ります。
ビューポート幅・高さの取得(ページ全体)
document.documentElement.clientWidth と clientHeight は、ページのビューポート(スクロールバーを除いた表示可能領域)を返します。ここが重要です:window.innerWidth/innerHeight はスクロールバーを含む場合があるため、「可視領域に収まるか」の判定には document.documentElement.clientWidth/Height がより実用的です。
基本の使い方(内側領域の計測と収まり判定)
要素の“使える内側サイズ”を読む
<div id="box" style="width:160px; padding:16px; border:4px solid #333; overflow:auto">
たっぷりテキスト…(長文)
</div>
<script>
console.log("clientWidth:", box.clientWidth); // 160 + 16*2(padding) = 192
console.log("clientHeight:", box.clientHeight); // コンテンツ行数に応じた高さ + padding(枠は含まない)
</script>
HTMLここが重要です:border を含まないため、内側でコンテンツが使える横幅・高さを直接得られます。スクロールバーが出ても、その厚みは client の値から差し引かれている(含まれない)点がポイントです。
テキストが“箱に収まるか”を判定する
<div id="title" style="max-width:240px; padding:8px; border:1px solid #ccc; white-space:nowrap; overflow:hidden; text-overflow:ellipsis"></div>
<script>
title.textContent = "とても長いタイトルが入ることを想定しています";
function fits() {
return title.scrollWidth <= title.clientWidth; // 実必要幅 <= 内側幅 なら収まる
}
console.log("収まる?", fits());
</script>
HTMLここが重要です:scrollWidth は「コンテンツが必要とする幅」、clientWidth は「実際に使える内側幅」。この比較だけで省略記号適用などの分岐が簡単になります。
似た値との使い分け(offset と rect との比較)
offsetWidth/Height との違い(外側寸法)
offset は content+padding+border+(必要なら)内部スクロールバーを含む「外側の箱」。ここが重要です:位置合わせや“外側のはみ出し”判定には offset、内側レイアウト(何列並べられるか、文字が収まるか)には client を使います。
getBoundingClientRect との違い(画面座標の精密計測)
getBoundingClientRect().width/height はビューポートに対する小数(サブピクセル)を返します。ズームや変形、スクロールが反映され、交差判定などに向きます。ここが重要です:client は整数で「内側領域」、rect は小数で「画面上の見え方」。精度が必要なら rect、内側レイアウトなら client です。
実践例(内側基準の配置・折りたたみアニメ・レスポンシブ判定)
内側右端にバッジをぴったり配置(padding を考慮)
<div id="card" style="position:relative; width:280px; padding:16px; border:1px solid #ccc">
<span id="badge" style="position:absolute; right:0; top:0">NEW</span>
</div>
<script>
// 内側右端に沿わせたいとき、clientWidth が“使える内側幅”
const innerRight = card.clientWidth; // content+padding の幅
// 右端は CSS の right:0 で寄せるのが簡単(計算不要)
// 明示計算するなら card.offsetLeft + padding を足すが、CSS寄せが堅牢
</script>
HTMLここが重要です:計算で合わせるより“position:absolute; right:0”のような CSS 寄せが安定ですが、内側領域を数値で扱う必要がある処理(キャンバスサイズ、グリッド計算)では client が基準になります。
折りたたみアニメの“内側高さ”基準で開閉
<div id="panel" style="overflow:hidden; transition: height .25s ease; padding:8px; border:1px solid #ddd"></div>
<script>
function openPanel(content) {
panel.textContent = content;
panel.style.height = "auto";
const h = panel.clientHeight; // 内側高さ(padding含む、枠は除外)
panel.style.height = "0px";
requestAnimationFrame(() => panel.style.height = h + "px");
}
openPanel("テキスト\nテキスト\nテキスト");
</script>
HTMLここが重要です:枠(border)を除いた“内側の見た目高さ”でアニメすると、コンテンツ量に応じて自然な動きになります。外側寸法で開閉したいなら offsetHeight を選びます。
レスポンシブで“何列並べられるか”を判定
<div id="grid" style="display:grid; gap:8px; border:1px solid #ccc; padding:8px"></div>
<script>
function canPlace(cols, cellWidth) {
const inner = grid.clientWidth; // グリッドの内側幅
const needed = cols * cellWidth + (cols - 1) * 8; // gap を考慮
return inner >= needed;
}
console.log("3列置ける?", canPlace(3, 120));
</script>
HTMLここが重要です:内側幅(client)を使えば、padding や枠の影響を避け、実際に配置可能かを正確に判断できます。
よくある落とし穴と回避策
「スクロールバーを含むか」の混乱
client は内部スクロールバーの厚みを含みません(その分だけ“使える内側領域”が減るため、値が小さくなります)。ここが重要です:スクロールバーのせいで計算が合わないと感じたら、内側計算には client、外側計算には offset を使い分けているか確認しましょう。
非表示要素は 0 を返す
display: none の要素は clientWidth/Height が 0 になります。事前計測が必要なら、visibility: hidden(見えないがレイアウト参加)に切り替えて測定します。ここが重要です:“今見えている内側領域”という定義に沿った計測が必要です。
整数丸めによる誤差
clientWidth/Height は整数で、小数点以下は切り捨てられます。ズームや CSS 変形、精密な重なり判定が必要なら getBoundingClientRect の小数値を使います。ここが重要です:精度が必要な場面では rect、レイアウトのざっくり判定なら client です。
位置とサイズの混同
位置は offsetLeft/Top か rect.left/top、サイズは clientWidth/Height か rect.width/height、と役割を分けます。ここが重要です:座標(どこにあるか)と寸法(どれくらいの広さか)を混ぜるとズレの原因になります。計算の基準(親内か画面か)も常に意識しましょう。
まとめ
clientWidth/clientHeight は「content+padding の内側領域」を整数ピクセルで返します。内側レイアウトや収まり判定、列数計算、折りたたみの自然高さなどに最適です。外側の位置合わせやはみ出し補正には offsetWidth/Height、画面座標の精密計測には getBoundingClientRect を使い分けます。スクロールバー・表示状態・丸め誤差の特徴を理解し、座標と寸法の責務を分けて扱えば、初心者でもズレの少ないレイアウトと気持ちよい UI を堅実に作れます。
