CSSを使って横方向にコンテンツをスクロール表示する要素を作っているとき、要素の内側の右側にmarginもpaddingも利かなくて困っていることはないだろうか?
今回はそんな問題を解決する方法を紹介する。
また、正しくやっているはずなのにうまくいってないときに見落としがちなポイントも併せて解説する。
スクロール要素の中で起きている問題
まずはscroll要素を確認してみよう。下のデモをよく見て、左右にスクロールしてほしい。
content-1
content-2
content-3
content-4
content-5
おわかりいただけただろうか?
content-5の右が詰まってる!
marginはどこにいったの?
もうちょっと例を確認しよう。
このようにcontentに影を付けてhoverエフェクトも付与したらこうなってしまう。
content-1
content-2
content-3
content-4
content-5
content-5の右側の影が切れてデザインが崩れちゃってる……
困った……原因はなんなのだろうか?
いちばん右側のmarginだけが効いてない理由
さて、なぜcontent-5の右のmarginが効かないのか?
理由は簡単であり、先ほどのふたつのデモの「demo」と「demo-content」の部分のCSSコードはこのようになっている。
上のコードをよく読んでもらうと理解できると思うが、「demo」要素にはwidthを指定していない。「demo」からあふれてはみ出した「demo-content」要素が「demo」要素を右へ右へと押し広げていく表示形式となっているのだ。
つまり、「demo」の幅は設定されていないので、内部の長さは無限と同じ状態となっている。だが、どこかで終わらせないと無限にスクロールすることになってしまう。なので、最後に表示されるコンテンツの右端で要素の幅を切って終わらせるようになっている。
こんなわけで右の間隔が無くなってしまっているのだ。
padding-rightは意味がない理由
じゃあ、「demo」要素に「padding-right」をあてればいいんじゃね?と考えた人もいるかもしれない。そして、実際にやってみて意味がないことに気が付くはずだ。
この現象をわかりやすくイラストにしたので見てほしい。
まず、これがスクロールバーが左端にあるとき。
そして、これがスクロールバーを右端まで動かしきったとき。
薄黄緑色のpadding-rightの位置が動いていないことがおわかりいただけただろうか?
先ほど、スクロール要素内部の幅は無限だと説明した。しかし、「demo」には幅がある。
「demo」には決められた幅がある、だが「demo」の内部には幅が無い……。なぜなら「demo」の中身は「demo」に収まっていないから。
このため、「demo」にはpaddingがかかるものの、その中身に影響を与えることは不可能なのだ。
こういったわけで、padding-rightは意味がないということになる。
最後のコンテンツの右側の間隔を空ける方法
それでは、この問題を解決する方法を紹介しよう。
まず、このデモを見て動かしてほしい。
content-1
content-2
content-3
content-4
content-5
content-5の右側にちゃんと空間がある!
このデモのCSSコードはこのようになっている。
先ほどの「いちばん右側のmarginだけが効いてない理由」を読んでいてピンときた人もいると思われるが、「overflow: scroll;」はふつう最後のコンテンツの右端で終わる仕組みとなっている。
ということは、最後のコンテンツだけ横のmargin分の長さをもった疑似要素を付け足してコンテンツの右側にはみ出すように配置すると、疑似要素のぶんだけスクロール要素内が押し広げられて、右のmarginが存在しているように見せることができるわけだ。
だいたいはこのような説明になる。
以上のようにすることで、右側の間隔を空けることができる。
うまくいっていないときに見直す箇所
さて、上記のようにやっているのにうまくいかない人はいるだろうか?
そのときは、スタイルシートのCSSをよくみてみよう。そして以下を確認してみよう。
「overflow: hidden;」がスクロール内のコンテンツにかかってない?
そのせいで「overflow: visible;」が無効化されてない?
CSSの基本として、子孫結合には強さが存在する。
より具体的に、そしてより上の親がセレクターに存在しているとそちらのほうが強くなるので上書きできないのだ。
こちらのデモを見てほしい。content-5の右側に空間が存在していないだろう。
content-1
content-2
content-3
content-4
content-5
そして、このデモのCSSコードはこうなっている。
このデモでは、CSSでより親のクラスである「.main」が前に付いて「.demo-content」に「overflow: hidden;」を指定してしまっている。
そしてoverflowプロパティのhiddenは、その要素からはみ出した部分を非表示にする役割を持っている。
このため、「overflow: visible;」が無効化されたので疑似要素も非表示化されてしまい、最後のコンテンツの右側に間隔が存在しなくなっているのだ。
これを解決するには、「.main」より上の親、例えば「.content」を使って「.content .mycus-demo .demo-4 .demo-content」と書いてやればいい。
もしくは、「.mycus-demo」と「.demo-content」の間にあるセレクターを全部選んでもっと具体的に命令する方法でもよい。
このふたつのうちのどちらかの方法で、「overflow: hidden;」を消すことができる。
もしWrodPressのテーマをカスタマイズしている最中に、うまくいっていない場合はこのことをよく覚えておいてほしい。
コンテンツの外観を整えるために「overflow: hidden;」とあらかじめ設定されているかもしれないからだ。
間隔を空ける方法のまとめ
「:last-child::after」で最後のコンテンツを選んで、右側にmarginぶんの長さの透明な疑似要素を作って配置しよう。
もしうまくいってなかったら、より強い子孫結合で「overflow: hidden;」が設定されていないか確認してみよう。
このふたつに注意してスクロール要素内の右の間隔を空けてみてほしい。
スクロール要素の右側の空間がどうしてもうまくいかないのでその原因を調べていたところ、様々なことがわかったので忘備録的に書き留めておくことにした。
特に「overflow: hidden;」が原因となって疑似要素が無効化されることになかなか気が付けなかったので。
この記事がカスタマイズの助けになり、また悩みを解決していると嬉しい。