IMUZA.com

Xserver<<WordPress(ConoHa)<<はてなブログ

ホーム / CSS / CSS:fixedの要素をスクロールバーなしでスクロールさせる

CSS:fixedの要素をスクロールバーなしでスクロールさせる

2021/06/6 CSS, javascript, WebTips

サイトのメニューをオーバーレイで出す場合には、その要素に position:fixed を指定する場合が多いと思いますが、要素の長さがデバイスの表示高よりも長い場合にスクロールさせ、かつ非タッチデバイスの場合にスクロールバーを非表示にし、背景を固定しスクロールバー非表示による要素のズレを解消する方法です。

  • メニューをオーバーレイでアニメーション
    • アニメーションの発火
    • メニューをドロップダウンさせる
    • メニューのスクロールバーを非表示にする
    • 背景のスクロールを止める
    • スクロールバー非表示による要素のズレを解消する
  • codepen サンプル

メニューをオーバーレイでアニメーション

まず、メニューをオーバーレイで上部からアニメーションでスライドさせてメニューをスクロール可能にする方法です。

<div class="content">
  <p>テキストコンテンツ</p>
  <!-- 確認のためにはブラウザの表示高以上のテキストコンテンツが必要 -->
</div>


<div class="btn" id="btn">
    MENU
</div>


<ul class="menu">
    <li>MENU1</li>
    <li>MENU2</li>
    <li>MENU3</li>
    <li>MENU4</li>
    <li>MENU5</li>
    <!-- 確認のためにはブラウザの表示高以上のメニューの高さが必要 -->
</ul>

まずこういう htmlを想定して考えてみます。テキストコンテンツはスクロールしなければ全文が読めない想定です。また、考え方だけのサンプルですの見た目などは考慮していません。

サンプルの完成形が codepenに置いてあります。

See the Pen
hide scrollbar but keep functionality
by ausnichts (@ausnichts)
on CodePen.

アニメーションの発火

メニューをドロップダウンさせる方法はいろいろありますが、今回は一番手短な javascriptのクリックイベントを使っています。

// メニューボタンにクリックイベントを設定する
document.getElementById('btn').addEventListener('click', function(){
  document.body.classList.toggle('active')
});

メニューボタンをクリックしますと、body要素に class='active' を追加します。

メニューをドロップダウンさせる

メニューボタンをブラウザの右上に固定し、ボタンの左側にドロップダウンさせるためにボタンの横幅を指定しておきます。

.btn {
  cursor: pointer;
  position: fixed;
  top: 0;
  right: 0;
  width: 80px;
  /* 以下は見やすくするため */
  background: red;
  text-align: center;
  padding: 20px 0;
  color: white;
}


.menu {
  position: fixed;
  top: 0;
  right: 80px;
  height: 0;
  overflow-y: auto;
  transition: height 500ms;
  /* 以下は見やすくするため */
  width: 100px;
  background: blue;
}
.menu li {
  /* 以下は見やすくするため */
  color: white;
  text-align: center;
  list-style: none;
}


.active .menu {
  height: 100%;
}

通常はメニューを height:0 にしておき、メニューボタンをクリックしますと body要素に class='active' が追加され、メニューの高さがブラウザの下まで伸びてきます。

なお、アニメーションに heightを使う場合は autoを指定してもアニメーションしませんので数値、または %や vhを指定する必要があります。javascriptを使えば正確にメニューの高さを計算できますが、今回のようにメニューをスクロールさせるのであれば、数値で指定すればいいと思います。また、max-heightに想定する高さよりも大きな数値をしておく方法もあります。ただ、いずれにしてもスクロールさせるのであればあまり意味がありません。

メニューのスクロールバーを非表示にする

これまでの設定ではメニューにスクロールバーが表示され見た目がよくありません。スクロールはできるけれどもスクロールバーを非表示にする方法です。

以下のサイトにその方法の記載があります。

  • How To Hide Scrollbars With CSS

/* メニューのスクロールバーを非表示 */
.menu {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.menu::-webkit-scrollbar {
    display: none;
}

詳細はリンク先をご覧ください。

背景のスクロールを止める

この設定では、メニューはスクロールするものの背景となっているテキストコンテンツもスクロールしてしまいます。

背景のテキストコンテンツがスクロールしないようにするには次のようにします。

/* 背景のスクロールを止める */
.active {
  overflow: hidden;
}

body要素に overflow:hidden を指定します。スクロールバーを消してスクロールできなくしてしまうということです。

ただし、iPhoneではこの指定ではスクロールを止められないと思います。最近の記事ではありませんが、iPhoneでスクロールを止める方法を下の記事で書いています。日常的に iPhoneを使っているわけではありませんので最近は検証していません。

www.imuza.com

スクロールバー非表示による要素のズレを解消する

以上の方法ですと、背景のスクロールは止まりましたが、スクロールバーを非表示にすることで body要素がスクロール幅分ひろがって要素全体がずれますので違和感があります。

CSSで処理する方法はないかと探しましたがいまのところ見つかりません。ですので、javascriptでスクロール幅を取得し、メニュー表示の際にその幅分のマージンや位置で調整する方法を取ってみます。なお、スクロールバーの幅は各ブラウザで異なっていますので決め打ちは出来ません。また、CSSで calc(100vw - 100%) としてスクロール幅を取得してみましたが、メニューを表示した瞬間にスクロールバーは消えてしまいますのでスクロールバーの値は 0 となってしまいます。

// スクロールバーの幅を取得し CSSカスタムプロパティーに定義する
const scrollbarWidth = (window.innerWidth - document.documentElement.clientWidth) + 'px';
document.documentElement.style.setProperty('--scrollbar-width', scrollbarWidth);

/* 背景のスクロールバー非表示による要素のズレを補正 */
.active .content {
    margin-right: var(--scrollbar-width);
}
.active .menu {
  right: calc(var(--scrollbar-width) + 80px);
}
.active .btn {
  right: var(--scrollbar-width);
}

あらかじめ javascriptでスクロールバー幅を取得し、CSSカスタムプロパティに設定しておきます。CSSで各要素のズレを補正します

codepen サンプル

以上の設定を codepenで確認できます。

See the Pen
hide scrollbar but keep functionality
by ausnichts (@ausnichts)
on CodePen.

劇場版「鬼滅の刃」無限列車編(通常版) [DVD]

劇場版「鬼滅の刃」無限列車編(通常版) [DVD]

  • 花江夏樹

Amazon

はてなブログ:ネイキッドドメインでのads.txtは不可能そう…
Ubuntu:21.04 日本語 Remix を入れてみた
Twitter
Facebook
ブックマーク
LINEで送る

最初のサイドバー

最新記事

2023/01/26

WordPress:メニューのid,classを整理カスタマイズ

2023/01/19

WordPress:JSON-LD構造化データをプラグインなしで出力

2023/01/11

WordPress:OGPタグをプラグインなしで挿入する

2022/12/27

WordPress:canonicalタグをプラグインなしで制御する

2022/12/21

WordPress:robotsメタタグをプラグインなしで制御する

最新記事を一覧で見る

よく読まれている記事

よく読まれている記事を一覧で見る

カテゴリー

  • はてなブログ214
  • WebTips108
  • javascript98
  • Joomla!88
  • Windows68
  • CSS63
  • Wordpress59
  • Joomla!更新53
  • Linux49
  • はてなテーマ45
  • Plamo33
  • Google32
  • はてなプラグイン25
  • php22
  • Node.js18
  • Ubuntu16
  • SASS16
  • laravel415
  • Chrome11
  • cms-style10
  • iPhone9
  • genesis6
  • ConoHa WING6
  • Git入門6
  • Python5
  • Android5
  • スマートフォン4
  • PC全般4
  • 静的サイトジェネレーター3
  • Firefox3
  • SSD3
  • Facebook3
  • Blankslate3
  • Docker3
  • Mactype2
  • GitHub2
  • youtube1
  • rails入門1
  • Twitter1
  • はてなブクマ1
  • 映画1
  • Xserver1

Footer

My Web Sites

  • @半径とことこ60分
  • そんなには褒めないよ。映画評
  • IMUZA.com
  • GitHub

Related Sites

  • WordPress公式
  • WordPress関数リファレンス
  • PHPマニュアル

Contact Us

  • お問い合わせフォーム
  • Twitter
  • Facebook
  • Feedly

Copyright © 2023 · IMUZA.com