Blog

ブログ

CSSのカスタムプロパティで快適な「vw」ライフを送ろう

前田 大地

CSSで要素の幅などを指定するとき、「vw」という単位があります。そのままだとちょっとクセの強い「vw」ですが、CSSのカスタムプロパティとJavaScriptを用いればもっと安心して使えるようになるよ。というお話です。

「vw」が破綻を招くワケ

「vw」は、便利ですが使いどころによってはレイアウトの崩壊を引き起こします。まず、「vw」を理解するために「%」との違いや、その問題点についてお話しします。

親要素を基準とした「%」

「%」は、CSSでよく利用される単位のひとつです。親要素の幅を100%としたときに何%になるか、を指定します。例えば、親要素の幅が500pxのとき、子要素に「width: 10%;」と指定すれば、500pxの10%なので50px幅になります。

ビューポートを基準とした「vw」

次に「vw」ですが、こちらはビューポートの幅を100%としたときの相対的なサイズを指定します。ビューポートというのは、ざっくり言えばブラウザ幅のことです。ブラウザ幅が500pxのときに「width: 10vw;」と指定すれば、500pxの10%なので50px幅になります。

「vw」の問題

「%」は親要素、「vw」はビューポートを基準とした相対的な単位であることが分かりました。ということは、つまり、親要素がブラウザ幅100%だったら「100% = 100vw」になるはずです。

しかし、ビューポートというのは少しやっかいで、スクロールバーまで含めたサイズが基準になっています。ブラウザ幅が500pxでスクロールバーが表示されているとき、「100vw」と指定すると、スクロールバーの分だけはみ出して画面幅をオーバーしてしまいます。

しかも、ブラウザによってスクロールバーの扱いが異なるのも非常にやっかいです。同じ「100vw」でも、スクロールするときだけバーが表示されるMac方式では画面にフィットして、常時スクロールバーが表示されるIE方式では画面からはみ出してしまうのです。

「%」はスクロールバーを除いた幅で計算してくれるため、上記のような問題は起こりません。そんなこともあって、「vw」はむやみに使えない残念な単位となっています。

CSSのカスタムプロパティで解決

でもやっぱり親要素の幅に影響されない「vw」は魅力的です。使い方によっては、これまで難しかった計算なんかもできるようになります。と、いうことで、CSSのカスタムプロパティを使って、スクロールバーを除外した「疑似vw」を作っちゃいましょう。

JavaScript

JavaScriptのclientWidthを使うと、スクロールバーを除いたビューポートサイズが取得できます。それを100分の1にして、「—vw」というカスタムプロパティとして登録します。

const setVw = function() {
  const vw = document.documentElement.clientWidth / 100;
  document.documentElement.style.setProperty('--vw', `${vw}px`);
}
window.addEventListener('DOMContentLoaded', setVw);
window.addEventListener('resize', setVw);

CSS

JavaScriptが動かない環境などで「—vw」が普通の「vw」と同じになるように、念のため初期値を指定しておきます。カスタムプロパティは、ルート要素(htmlタグ)に指定します。

:root {
  --vw: 1vw;
}

vwを置き換えて使う

使い方はかんたんです。「—vw」というカスタムプロパティが1vw相当なので、calcを使って必要な数を掛けてあげるだけです。

/* vwを使った記述を…… */
.style {
  width: 50vw;
}

/* --vwに置き換える! */
.style {
  width: calc( var(--vw) * 50 );
}

やってみた感想

もうoverflow-x: hidden;には頼らない!

Web Designer / Developer

前田 大地

沼津高専中退。デザイン会社、システム開発会社を経てセブンシックスを設立。マーケティング、デザイン、テクノロジーに精通するオールラウンダーとして、県内の中小企業に向けた戦略型ホームページ制作を開始。一方で、都内の広告代理店からの要請で大企業案件にも多数参加。企業が本当に必要とするホームページ制作とは何か、を日々探求している。

Blog top