[Next.js]スクロール幅を除いたvwサイズを計算する

ビューポートを基準にしたvwは、画面幅いっぱいに表示したい時などに重宝します。

ただ、Windowsなどのスクロールが常に表示されているブラウザは、スクロール幅を含めたビューポートが100vwとなります。
そのため、スクロール幅を除いて画面いっぱいに表示したいときは100%を設定します。

それでも100vwを使いたい場面があります。
今回は、スクロール幅を除いたvwサイズを計算します。

本記事のNextjsのバージョンは”13.5.4″となります。

目次

vwサイズの初期設定

vwサイズのスタイル設定をします。
–vw変数を後述のJavaScriptで動的に変更していきます。

import { createGlobalStyle } from "styled-components";

export const GlobalStyle = createGlobalStyle`
:root {
  --vw: 1vw;
}
`;

_app.page.tsxで読み込み、全てのページで適用されるようにします。

<GlobalStyle />

–vwを変更するhooksを実装

hookで呼び出すようにします。

100vwはスクロールバーの幅も含めたサイズになるため、スクロールバーを除いたビューポートサイズを–vw変数に格納し、calc(var(--vw) * 100) のようにすることでスクロールバーを含まないサイズを設定します。
vwはresizeが走るたびに再計算するようにします。

import { useEffect } from "react";

export function useVw() {
  useEffect(() => {
    const setVw = () => {
      const vw = document.documentElement.clientWidth / 100;
      document.documentElement.style.setProperty("--vw", `${vw}px`);
    };

    setVw();
    window.addEventListener("resize", setVw);

    return () => {
      window.removeEventListener("resize", setVw);
    };
  }, []);
}

CSSでスクロールバーを除いたvwを定義する

–vwには1vwの値を計算して入れているので、100を乗算することで、スクロール幅を考慮したCSSを定義できます。

width: calc(var(--vw) * 100);

Summary

Windowsで見るとスクロールバーが常に表示されているため、vwを使うと、横スクロールがでてどうしよっ…となったのですが、これで解決です。

よかったらシェアしてね!
目次