にしし ふぁくとりー:西村文宏 個人サイト

"JavaScript Tips Factory" : Presented by Nishishi. Since 1997.

ボックスの高さを、スクロールバーを含まない全画面(または画面半分)にぴったり合わせるJavaScript [イベント,装飾・内容変更,計算・変換]

画面(ブラウザ)の全面ぴったりにボックスの高さを広げたい場合、横スクロールバーが表示されていない状況ならCSSでheightプロパティに値100vhを指定すれば話が早いのですが、スクロールバーが表示されている場合にははみ出してしまいます。その場合は、JavaScriptでdocument.documentElement.clientHeightの値を得てからボックスのサイズを変更すると良いでしょう。注意点としては、window.innerHeightは使わないことです。高さ(縦方向)だけでなく横方向にも全画面に広げたい場合は、横幅についてはJavaScriptを使うまでもなくCSSでwidth:100%;(100vwにはしない)と書いていれば充分ですが、ついでにdocument.documentElement.clientWidthを使って変更しても良いでしょう。例えば、横方向にも画面の半分サイズにしたい場合にはこれで計算式が書けます。

ボックスの高さを全画面(または画面半分)ぴったりサイズに調整したい

あるボックスの高さを、JavaScriptを使って全画面(ブラウザの描画領域の高さぴったり)サイズに合わせたい場合は、document.documentElement.clientHeightプロパティの値を使うのが簡単です。
document.documentElement.clientHeightで、スクロールバーのサイズを除いた画面の高さが分かりますから、これにボックスの高さを合わせれば良いでしょう。

2で割れば画面半分の高さにもできますし、3で割って画面を3等分する高さに調整することもできます。

ボックスの高さを(スクロールバーは除いて)全画面ぴったりサイズに調整した表示例 ボックスの高さを(スクロールバーは除いて)画面半分ぴったりサイズに調整した表示例 ボックスの横幅を(スクロールバーは除いて)画面の3等分サイズに調整した表示例

上図は、左から順に、

  • ボックスの高さを(スクロールバーのサイズは除いて)全画面ぴったりサイズに調整した表示例
  • ボックスの高さを(スクロールバーのサイズは除いて)画面半分ぴったりサイズに調整した表示例
  • ボックスの横幅を(スクロールバーのサイズは除いて)画面の3等分サイズに調整した表示例

です。具体的な書き方(ソース)は後述します。

スクロールバーが表示されない状況なら、CSSの記述だけで済むのだが

そもそも、スクロールバーが表示されない状況でなら、わざわざJavaScriptを使うまでもなく、CSSだけでボックスの高さを全画面に広げられます。
方法はとても簡単で、heightプロパティの値に、単位vh(=Viewport Height)を使って100vhと指定するだけです。

CSSソース

.targetbox {
   height: 100vh;   /* 高さを画面の高さに合わせる */
}

スクロールバーが出ない状況でなら、ボックスの高さはCSSだけで全画面ぴったりサイズに調整できる

このように、CSSで単位vhを使って画面の高さに合わせる方法の詳しい解説は、別途CSS Tipsの記事「テキスト入力欄の高さを画面の高さ100%に合わせるCSSには、単位vhを使うと楽」をご覧下さい。

横スクロールバーがあると、CSSの「height:100vh;」では、はみ出してしまう

しかし、問題はスクロールバー(横方向にスクロールするための横スクロールバー)が現れている状況です。
CSSの100vhで表される高さにはスクロールバーの領域も含むので、もし横方向にスクロールする「横スクロールバー」が表示されている状況では、ボックスサイズは(スクロールバーのサイズ分だけ)はみ出してしまいます。下図のように。

横スクロールバーがあると、CSSの「height:100vh;」では下方向に《はみ出して》しまう表示例

そこで、スクロールバーの分量を除いた画面の高さを取得できるJavaScriptの出番です。

スクロールバーを含まない高さを取得できるdocument.documentElement.clientHeight

document.documentElement.clientHeightというプロパティで、スクロールバーの太さを含まない画面高さが得られます。
なんだかすごく長い記述で冗長っぽく感じますが、documentElementの部分もこのままこの通りに書きます。

例えば下記のように、対象のボックスのスタイル「height」プロパティに対して、この値を代入すれば良いでしょう。

JavaScriptソース

document.getElementById('targetbox').style.height = document.documentElement.clientHeight + "px";

数値だけを代入するのではダメで、単位「px」も文字列として加えた上で代入しないといけない点に注意して下さい。CSSとして成立する値(文字列)にする必要があります。

これを使うと、下図のように横スクロールバーが表示されている状況でも、ちゃんとスクロールバーの幅を除いた画面の高さぴったりにボックスの高さを合わせられます。

ボックスの高さを、スクロールバーの幅を含まない画面の高さに合わせた表示例

document.documentElement.clientHeightの真ん中にあるdocumentElementという記述を見ると、なんだか「ここは任意の要素名に置き換えてね」という意味で書いているのかな? と誤解されるかもしれませんが、そうではありません。このまま「documentElement」と書きます。

注意:window.innerHeightではスクロールバーを含む高さが得られる

画面(ブラウザの描画領域)の高さを取得できるプロパティには、document.documentElement.clientHeightの他に、window.innerHeightもあります。「画面の高さを得たい」と思ったときに真っ先に思いつくのはむしろこちらのwindow.innerHeightの方かも知れません。

しかし、window.innerHeightではスクロールバーも含んだ全画面の高さが得られてしまうので、スクロールバーの分を差し引いた高さを得たい場合には使えません。

以下に、両者を使った場合のソースと、それを表示したサンプル画面を掲載しておきます。

JavaScriptソース

// スクロールバーのサイズを『含まない』高さに合わせる(=はみ出ない)
document.getElementById('targetbox').style.height = document.documentElement.clientHeight + "px";

JavaScriptソース

// スクロールバーのサイズを『含む』高さに合わせる(=はみ出る)
document.getElementById('targetbox').style.height = window.innerHeight + "px";

表示例は下図の通りです。
document.documentElement.clientHeightの方は(スクロールバーを含まない高さに合うので)はみ出しませんが、window.innerHeightの方は(スクロールバーを含む高さに合うので)はみ出してしまいます。

window.innerHeightとdocument.documentElement.clientHeightではスクロールバーの分量だけ異なる

絶対に横スクロールバーが表示されないと分かっている状況ならどちらを使っても同じことですが。せっかく「スクロールバーの太さを含めない」値を取得できるプロパティが存在するのですから、そちらを使っておく方が無難でしょう。

注意:document.documentElement.clientHeight を使っているのに横スクロールバーの幅が除外されていないと感じる場合の注意

document.documentElement.clientHeightの値を参照してボックスの高さを調整しているにも関わらず、スクロールバーの幅が除外されていないように見える場合があります。
つまり、document.documentElement.clientHeightを使っても、window.innerHeightを使った場合と同じように表示されてしまうケースです。

このような現象に遭遇した場合は、
スクリプトを実行しているタイミング(記述位置)を確認してみて下さい。

「document.documentElement.clientHeightプロパティの値を参照した瞬間」には、まだ横スクロールバーが現れていないような位置で実行している可能性があります。

画面に横スクロールバーが出現するかどうかが状況次第の場合や、横スクロールバーの出現要因がページの末尾付近にあるような場合は、「ページの読み込みが完了した後のタイミングでJavaScriptが実行されるようにする」方が無難です。

ボックスの横幅も全画面に広げたい場合

装飾対象がブロックの場合は、ほぼ何も考えなくても横方向には全画面に広がります。
テキストエリアなど、横幅がデフォルトでは全画面に広がらない要素を対象にしたい場合は、自力でwidth: 100%;のようにCSSを指定すれば済みます。widthプロパティの値を100%にするだけで、スクロールバーの幅は含まないサイズに調整されるため、(高さの場合と比べて)横方向を全画面いっぱいに広げるのは簡単です。

例えばCSSソースを以下のように書けば済みます。

CSSソース

.targetbox {
   width:  100%;    /* 横幅を画面いっぱいに広げる(=スクロールバーの幅は除外) */
}

このCSSを使ってボックスを表示すると、下図のようにスクロールバーが表示されている状況でも、スクロールバーの幅を除いた画面サイズに合致するよう広がります。

ボックスの縦横を(スクロールバーは除いて)全画面ぴったりサイズに調整した表示例

もちろん、高さと同様にJavaScriptを使って横幅を指定する方法も使えます。高さのプロパティ名が「clientHeight」だったことから容易に想像が付くでしょうが、横幅は「clientWidth」で得られます。スクロールバーの幅は含みません。

JavaScriptソース

// スクロールバーのサイズを『含まない』横幅に合わせる
document.getElementById('targetbox').style.width = document.documentElement.clientWidth + "px";

高さをJavaScriptで調整しているなら、横幅もついでにJavaScriptで書いておいた方が(ソースを読む際に)分かりやすいかもしれません。

注意:横方向へ全画面に広げる際に、単位vwを使って「width:100vh;」とはしない

画面いっぱいの高さを示すCSSが「100vh」なら、画面いっぱいの横幅を示すCSSは「100vw」です。

  • 単位vh = Viewport Height
  • 単位vw = Viewport Width

しかし、ボックスのサイズを全画面にするために、これらの「100vw」・「100vh」を使ってしまうと、スクロールバーの幅の分だけはみ出てしまいます。

CSSソース

.targetbox {
   width:  100vw;   /* はみ出るので注意! */
}

100vwだとスクロールバーの幅を含むのではみ出る

上図のように、はみ出てしまいます。widthプロパティの値には素直に100%を使っておきましょう。
その方が、親要素の余白量なども考慮して最大値に広がってくれるので使い勝手が良いです。

横幅の調整にもJavaScriptでdocument.documentElement.clientWidthを使う方法(計算式を使って画面を3等分にしたい場合などに)

横方向にも全画面ではなく「画面の半分にしたい」とか「画面の3分の1にしたい」というような場合には、document.documentElement.clientWidthを使って「スクロールバーを含まない横幅」を取得して、割り算すれば望みの値が得られます。

例えば、ボックスの横幅を、画面の3分の1にすることで、全画面にボックスを3つ均等に並べたい場合は、以下のようにJavaScriptソースを書けば良いでしょう。

JavaScriptソース

// 横幅を(スクロールバーのサイズを含まない)画面の1/3サイズにする
document.getElementById('targetbox').style.width = ( document.documentElement.clientWidth / 3 ) + "px";
// 高さを(スクロールバーのサイズを含まない)画面の高さに合わせる
document.getElementById('targetbox').style.height = document.documentElement.clientHeight + "px";

表示例は下図の通りです。

ボックスの横幅を画面サイズの3分の1に調整した表示例

スクロールバーの幅を除いて、画面をぴったり3等分できています。

ソース例:ボックスの高さを(スクロールバーは除いて)全画面ぴったりサイズに調整

最後に、具体的なHTML・CSS・JavaScriptソースの記述例を2つほどご紹介しておきます。まずは、ボックスの横幅と高さを(スクロールバーは除いて)全画面ぴったりサイズに調整する例です。

HTMLソース

<div id="targetbox">ボックス</div>

JavaScriptソース

// スクロールバーのサイズを『含まない』高さに合わせる
document.getElementById('targetbox').style.height = document.documentElement.clientHeight + "px";

CSSソース

#targetbox {
   width: 100%;                   /* 横幅を画面いっぱいに広げる */
   border: 2px solid #0a8;        /* 枠線 */
   border-radius: 3.6em;          /* 角丸 */
   padding:1.5em;                 /* 内側の余白量 */
   box-sizing: border-box;        /* ※内側の余白を設けたり、枠線を加える場合には、この記述が必須(この記述がないと、はみ出ます) */
   background-color: yellowgreen; /* 背景色 */
   color: white;                  /* 文字色 */
}

上記のソースを表示すると、下図のような感じに見えます。

ボックスの高さを(スクロールバーは除いて)全画面ぴったりサイズに調整した表示例

縦横にスクロールバーが存在する場合でも、スクロールバーの幅を除いて全画面ぴったりサイズに装飾できています。

ソース例:ボックスの高さを(スクロールバーは除いて)画面半分ぴったりサイズに調整

次に、ボックスの高さを(スクロールバーは除いて)画面半分ぴったりサイズに調整したい場合(横幅は画面いっぱい)のソース例です。

HTMLソース

<div class="box" id="targetbox1">ボックス</div>
<div class="box" id="targetbox2">ボックス</div>

JavaScriptソース

// スクロールバーのサイズを含まない「画面の高さ」の半分に合わせる
document.getElementById('targetbox1').style.height = ( document.documentElement.clientHeight / 2 ) + "px";
document.getElementById('targetbox2').style.height = ( document.documentElement.clientHeight / 2 ) + "px";

同じ値を指定するなら、「画面の高さ半分」の値を変数に一旦入れておくとかした方がスマートだとは思いますけども、まあ行数を短くして分かりやすくするために冗長にしておきました。

CSSソース

.box {
   box-sizing: border-box;        /* ※内側の余白を設けたり、枠線を加える場合には、この記述が必須(この記述がないと、はみ出ます) */
   width: 100%;                   /* 横幅を画面いっぱいに広げる */
   border: 2px solid black;       /* 枠線 */
   border-radius: 3.6em;          /* 角丸 */
   padding:1.5em;                 /* 内側の余白量 */
   color: white;                  /* 文字色 */
}
#targetbox1 { background-color: skyblue; border-color: royalblue; } /* 背景色と枠線色を別に指定 */
#targetbox2 { background-color: pink;    border-color: brown; }     /* 背景色と枠線色を別に指定 */

上記のソースを表示すると、下図のような感じに見えます。

ボックスの高さを(スクロールバーは除いて)画面半分ぴったりサイズに調整した表示例

スクロールバーのサイズを除いて、画面の縦をぴったり半分に割れていることが分かります。

CSSではなくJavaScriptを使って調整するデメリット

デメリットという程ではないかもしれませんが、CSSだけではなくJavaScriptを使ってブロックのサイズを調整するにはデメリットもあります。

CSSだけで作ると、ユーザがブラウザのウインドウサイズを変更した場合でも、何もせずに自動でサイズが再調整されるメリットがあります。
JavaScriptで作った場合は、スクリプトが実行された瞬間の画面サイズを基準にして計算されるため、後からユーザがブラウザのウインドウサイズを変更しても追随はしません。
これに対応しようと思うと、window.onresize みたいなイベントを使って、再計算させる関数をその都度呼び出す必要があるでしょう。

例えば以下のような感じで。

JavaScriptソース

// ユーザがウインドウサイズを変更した際に、毎回ボックスのサイズも再計算する
function boxResizer() {
   document.getElementById('targetbox1').style.height = ( document.documentElement.clientHeight / 2 ) + "px";
   document.getElementById('targetbox2').style.height = ( document.documentElement.clientHeight / 2 ) + "px";
}
boxResizer();                                  // 最初に1度実行しておく
window.addEventListener("resize", boxResizer); // リサイズイベントが発生したら再実行する

上記のJavaScriptソースではすべて、対象要素を一意に特定するgetElementByIdメソッドを使いましたが、サイズ調整したいボックスがたくさんある場合には記述量が多くなって激しく面倒です。
その場合には、getElementsByClassNameメソッドかquerySelectorメソッドを使ってclass名で対象を特定する方が楽でしょう。ただ、ループを使って「該当要素すべてを対象に繰り返し処理する」記述が必要になるので、ボックスの数が少ない場合にはかえってソースが長くなって分かりにくくなると考えて、ここではその方法は使いませんでした。

以上、ボックスの高さをスクロールバーを含まない全画面(または画面半分)にぴったり合わせるJavaScriptの話でした。

関連記事:
●「テキスト入力欄の高さを画面の高さ100%に合わせるCSSには、単位vhを使うと楽」(@CSS Tips)

()

JavaScript TIPSふぁくとりーの主要なカテゴリ

下記のカテゴリに区分して、JavaScriptに関するTIPSを公開しています。カッコ内の数字は、該当する記事の件数です。

著者紹介


にしし(西村文宏)

にししでございます。本書いたり記事書いたりしてます。あと萌えたり。著書5冊発売中です(Web製作系4冊+小説1冊)。著書や記事は「西村文宏」名義。記事は主にAll Aboutで連載。本の最新刊は2011年3月に発売されたライトノベルでございますよ。

Twitter:にしし/西村文宏
にしし/西村文宏 on facebook にしし/西村文宏 on mixi フォローはお気軽に!

にしし(西村文宏)連絡先
☕ コーヒーをおごる

著書一覧と詳細

関連するかもしれない情報など

▼このページに関連しそうな記事が約8本くらい自動表示されています。(たぶん)

--- 当サイト内を検索 ---