スクロールさせる領域だけどスクロールバーは非表示にしたい。


この記事には、サンプルへのリンクを掲載しておりますが、OS側の設定などで『スクロールバーを非表示』などにしていると、何言ってんだこいつってなると思います。
Macの方は [システム環境設定]-[一般]からスクロールバーを表示するようにしてから読むとわかりやすいと思います。
Windowsは標準で出てると思います。自信ないですけど。

本記事のサンプルです。適宜ご参照ください。
http://codepen.io/naru0504/pen/dYpLJg

※ styleタグとか使っているのはQiita上で動くと勘違いしていたからです。いやだってKobito上で適応されていたんですもん……。公開してから知ったんですもの……。書きなおすのがめんどうでそのままにしてあります。

スクロールバーを消してほしいという要望があった。

今回の記事では以下のような例を扱います。あるエリアに固定されていて、スクロールできるというようなものです。

<div>
  <ul class="sample1-ul">
    <li class="sample1-li">この領域はスクロールします</li>
    <li class="sample1-li">右側にスクロールバーが出ます</li>
    <li class="sample1-li">今回の記事では</li>
    <li class="sample1-li">このスクロールバーを消します。</li>
    <li class="sample1-li">話を簡潔にするために</li>
    <li class="sample1-li">横スクロールバーは</li>
    <li class="sample1-li">出していません。</li>
    <li class="sample1-li">(´ぅω・`)ネムイ</li>
  </ul>
</div>
.sample1-ul {
  padding: 0;
  width: 300px;
  height: 88px;
  overflow-y: scroll;
  border: 1px solid #ccc
}
.sample1-li {
  list-style: none!important;
  padding: 4px
}

.sample1-li:nth-child(even) {
  background: #eff
}

.sample1-li:nth-child(odd) {
  background: #fec;
}

CSS3らへんで確認もれているだけで実はそこらへんの操作できるようになっていないかな?と思い調べてみました。
ぐぐっても出てくる情報は割とoverflow:hiddenでいけますみたいな記事がたくさん出てくる。
それスクロールバーを非表示になるけど、スクロールできなくなるんだよなあっていう。

WebKit限定の::-webkit-scrollbar

::-webkit-scrollbar系の操作は当然ながらWebKit系のブラウザでしか動かないから、FireFoxは当然ダメ。IEは確認する気にならないから知らない。
ちなみに実装するならこれだけでスクロールバーを消せる。

実装してみると、ChromeやOperaだとスクロールバーが見えない。しかしFireFoxで見るとスクロールバーが見えてしまうはずです。

<div>
  <ul class="sample2-ul">
    <li class="sample2-li">この領域はスクロールします</li>
    <li class="sample2-li">Webkit系のブラウザで</li>
    <li class="sample2-li">スクロールバーは消えています</li>
    <li class="sample2-li">FireFoxでは出ます</li>
    <li class="sample2-li">話を簡潔にするために</li>
    <li class="sample2-li">横スクロールバーは</li>
    <li class="sample2-li">出していません。</li>
    <li class="sample2-li">(´ぅω・`)ネムイ</li>
  </ul>
</div>
.sample2-ul {
  padding: 0;
  width: 300px;
  height: 96px;
  overflow-y: scroll;
  border: 1px solid #ccc
}
.sample2-ul::-webkit-scrollbar {
  display: none;
}
.sample2-li {
  list-style: none!important;
  padding: 4px
}

.sample2-li:nth-child(even) {
  background: #eff
}

.sample2-li:nth-child(odd) {
  background: #fec;
}

Electonで専用アプリケーション開発する場合など、この方法がよいと思います。
他にもいろいろとありますのでご参考あれ。
Webkit独自拡張でスクロールバーのデザインを変更する
Webkit

でもWebプラットフォームはそうはいかないんじゃああぁ!
モバイル限定ならWebKitだけで十分なんですけどね。

すべてのブラウザに対応したやり方

::-webkit-scrollに比べるとちょっとトリッキーに思えるかもしれない方法で実現してみました。

<div class="sample3-wrap">
  <ul class="sample3-ul">
    <li class="sample3-li">この領域はスクロールします</li>
    <li class="sample3-li">すべてのブラウザで</li>
    <li class="sample3-li">おそらくですけど</li>
    <li class="sample3-li">スクロールバーは出ません。</li>
    <li class="sample3-li">横スクロールバーは</li>
    <li class="sample3-li">もちろん出ません。</li>
    <li class="sample3-li">(´ぅω・`)ネムイ</li>
  </ul>
</div>
.sample3-wrap {
  padding: 0;
  width: 300px;
  overflow-x: hidden;
  overflow-y: hidden;
  border: 1px solid #ccc
}
.sample3-ul {
  margin: 0;
  padding: 0;
  height: 96px;
  width: calc(100% + 17px);
  padding-right: 17px;
  overflow-y: scroll;
}
.sample3-li {
  list-style: none!important;
  padding: 4px
  width: 300px;
}

.sample3-li:nth-child(even) {
  background: #eff
}

.sample3-li:nth-child(odd) {
  background: #fec;
}

何をしているのか?

親要素.sapmle3-wrapより子要素.sample3-ulをスクロールバー分大きくして、親要素からはみ出た要素(スクロールバー)をdisplay:hiddenしています。スクロールしているのは子要素の方です。
スクロールバーが出現していない場合はただの空白のhiddenされている状態です。
ちなみに気付かれた方もいると思いますが、sample1,2ではulにborder付けてましたが、今回の例ではulの右端ははみ出てhidden状態なので親要素の方にborderつけています。

[追記]
Twitterでご指摘をいただき気付いたのですが、一番内側の要素(例で言うとli)が親要素分の幅いっぱいに広がるものだと、スクロールバーが出現していないときに17px分隠れてしまいます。
なのでサンプルコードのliに幅指定をwrapと同じサイズで明記しました。
ここの幅指定をしない場合は、中に幅17px分のdiv要素を入れるなどの対応方法もあります。
[/追記]

弱点は幅を明記しなきゃあかんのと親要素を用意しなきゃいけないところですね。
特に幅の方はスクロールバー分の幅も考えなくてはいけなくて「だいたい16pxなんじゃないの?」ってテキトーに設置して「あら、綺麗な数値」って思ってたらIEで1pxくらいはみ出てたので17pxに変更した次第です。
非常にキリの悪い数値で気持ち悪くてツラいです。

総括

もっといい方法あるよって人は教えてください!!
JSですっきりやる方法があるなら割と興味あります。

この記事を書きながら他の方法ないか調べてみたけどもなかなか見つからない。結局こういう方法を取るしかないなあって採用しました。
-webkit-toolbarはすばらしいんですけど、こういうやり方できたらなーっていうのはいつもブラウザ独自拡張ばかりですね
標準化は遅いし、独自拡張ばかりで、ブラウザというプラットフォームって複雑ですよね。

序盤で記載した『overflow:hiddenでスクロールバー消えます!』って情報について。
これはあたらしいウィンドウで何か開いたりとかスクロールまったくしないサイトだっていう前提があるんだと思います。(そういうのは昔のサイトにはよくあったと思う)
でも、いつの間にかその前提を書くことなく【スクロールバー非表示=overflow:hidden】みたいな公式になっててそれがくり返されてきてるから期間絞ってもその情報が出てくるから割と困った。そもそもoverflowってある要素に入りきらないものをどう扱うかなので(ry

余談ながら、見栄え調整でnth-childとか使ったおかげでこれSassでもLESSでもStylusでもいいからネストをもっとラクに書きたい願望にすごく駆られました。最初から外部にサンプル載せることになるってわかっていればそうするので次こういう機会があれば使っていると思います。

前記事 - PhpStormでgit使おうとしたらエラー