web関連

【CSS,JS】100vwを使用したときにスクロールバーの幅を取得する件

100vwでサイトの全体幅を取得しようとしたときに、スクロールバーの幅(16px)を含んでしまいデザインが崩れたので備忘録

vwはスクロールバーを含む

どうにもchrome、firefox、ie、edgeとsafariだとvwの挙動が異なるようで

  • chrome、firefox、ie、edgeのvwはスクロールバー(16px)を含む
  • safariのvwはスクロールバー(16px)を含まない

っぽい、僕が確認した限りだと

なので「ブラウザハックでsafariのみ書き換える方法」と「javascriptを使ってスクロールバーを除いた全体幅を取得する方法」の2パターンで対応してみた

ブラウザハックでsafariのみ書き換える方法

safariのみにcssを適用させるブラウザハック

_::-webkit-full-page-media, _:future, :root .css-property{
  width: 100vw;
}

これで済めば問題ないだろうけど、Windowsのパソコンで確認ができないんだよね
chromeとかedgeでエミュレーション機能があるからそれでsafariの表示を確認したんだけど反映されてなかった

ので、javascriptを使ってスクロールバーを除いた全体幅を取得してしまえばいいんじゃないかと思ったのが以下

javascriptを使ってスクロールバーを除いた全体幅を取得する方法

やり方としては、javascriptのclientWidthでスクロールバーを除いた幅を取得し、取得した幅をカスタムプロパティでcssに適用させる

<style>
.elem{
  width:100vw;// 変数をサポートしていないブラウザのフォールバック
  width:(var(--vw);//
}
</style>

<script>
let vw = document.body.clientWidth;// スクロールバーを除いた幅を取得
document.documentElement.style.setProperty('--vw', vw + 'px');
</script>

これでスクロールバーを除いた幅をどのブラウザで取得できる

おまけ:今回に至る経緯

親要素から子要素をはみ出させる以下の記述を使って子要素を親要素からはみ出させ、position:absoluteをつかって左右それぞれの画面縁に要素を配置したらsafari以外のブラウザでそれぞれ8pxずつ画面縁にめり込んでてvwがスクロールバーを取得することに気づいた

margin:0 calc(((100vw - 100%) / 2) * -1);

過去にスクロールバーに苦しめられてたから8pxという数字を見てすぐにスクロールバーか…って気づいた
こうやって人は賢くなっていくんだね

CSSのみでスクロールバーを除いた画面幅を取得できないかなと考えたけど子要素だと100vw使わないと全体の幅を取得できないから無理だと気づいた
親要素だったら「width: calc(100vw - (100vw - 100%));」でスクロールバーを抜いた全体幅を取得できる

Leave a Comment

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。