【CSS】Safari 16.0でフルサポートされたoverflow: clipが便利
overflow: clip
の概要
overflow: clip
はChrome・Edgeでは90から[1]、Safariでは16.0から[2]フルサポートされた比較的新しい値です。
overflow: clip
の特徴には
① コンテンツを要素のパディングボックスに合わせて切り取る
② プログラム的なスクロールも含め、全てのスクロールを禁止する
③ overflow-x
またはoverflow-y
を使用して1つの軸にクリッピングを適用することができる
があります。[3][4]
①はoverflow: hidden
と同じですが、②、③の特徴はhidden
とは異なり、このことによってhidden
ではできなかったことを簡単にできるようになりました。
本記事では、clip
によってでできるようになったこと2つを紹介します。
position: sticky
の祖先要素に使える
1. position: sticky
で固定したい要素の祖先要素にoverflow: hidden
(※)が適用されていると、position: sticky
がうまく効かないことがあります。
特に多いのはbody {overflow-x: hidden}
したいけど、bodyの子孫要素にposition: sticky
を使いたい場合ではないでしょうか。
このようなときにoverflow-x: hidden
の代わりにoverflow-x: clip
を使うと、position: sticky
を意図通りに適用することができます。
※ overflow-x: hidden
のみ、またはoverflow-y: hidden
のみの場合も含みます。文章の読みやすさのために省略してoverflow: hidden
と書いていきます。
overflow: hidden
するとstickyが効かなくなる理由
祖先要素にposition: sticky
が適用された要素は、文書の通常のフローに従って配置され、さらに、直近のスクロールの仕組みを持つ祖先要素に対してtop,right,bottom,left
の値で設定された位置で固定配置されます。
このスクロールの仕組みを持つ祖先要素がoverflow: auto
またはoverflow: scroll
の要素だけなら、想像通りの振る舞いになると思います。
しかし、overflow: hidden
もスクロールの仕組みを持つ要素とされているのが混乱する原因です。
hidden
...内容はプログラム的に (例えば、 offsetLeft のようなプロパティの値を設定する方法などで) スクロールすることができますので、要素はスクロールコンテナーになります。
overflow - CSS | MDN
以下でstickyがうまくいく例とoverflow: hidden
によってうまくいかない例を見ていきましょう。
要素の親子関係は以下のようになっています。
.container // .container__innerの親
└ .container__inner // .stickyBoxの親
└ .stickyBox
うまくいく例
.stickyBox
はoverflow-y: scroll
が適用された.container
にtopの位置で張り付いています。.stickyBox
の親要素の.container__inner
はoverflow: visible
(デフォルト値)です。
うまくいかない例
.stickyBox
の親要素.container__inner
にoverflow-x: hidden
すると、.stickyBox
はこれに貼り付いてしまい、stickyが効いていないように見えます。
position: sticky
の祖先要素にoverflow-x: clip
してみた
前述の特徴②にあるように、overflow: clip
はプログラム的なスクロールも含め、全てのスクロールを禁止するので、「はみ出した部分を切り取りたいだけなのに、意図せずstickyの貼り付く対象になってしまう」のを防ぐことができます。
先ほどのうまくいかない例の.container__inner
にoverflow-x: clip
を適用してみましょう。
.stickyBox
は親要素の.container__inner
ではなく祖先要素の.container
に貼り付いて、意図した振る舞いになりました。
2. 要素外にはみ出した部分をx/yどちらかの方向だけ切り取ることができる
overflow: hidden
では、はみ出したコンテンツをx/yどちらかの軸方向のみで切り取ることできませんでした。
例えば、x方向ははみ出した部分を切り取り、y方向ははみ出した部分をそのまま表示したい場合、
overflow-x: hidden; overflow-y: visible;
としても、y方向のはみ出た部分は表示されません。
理由は、overflow-x
またはoverflow-y
の一方にhidden/scroll/auto
が設定されているとき、もう一方に設定されたvisible
はauto
になってしまうからです。
一括指定の次の各プロパティとして
overflow-x: 指定通り、ただし overflow-x と overflow-y のどちらかが visible でも clip でもない場合は、 visible/clip はそれぞれ auto/hidden と計算される
overflow-y: 指定通り、ただし overflow-x と overflow-y のどちらかが visible でも clip でもない場合は、 visible/clip はそれぞれ auto/hidden と計算される
overflow - CSS | MDN
overflow-x: clip
またはoverflow-y: clip
はもう一方のoverflow
に干渉しないので、一方の軸方向ではみ出た部分を切り取り、もう一方の軸方向では表示することができます。
Discussion
これのせいでどれだけ苦しめられたか。。
とてもいい記事ありがとうございます!
共感です。。
嬉しいコメントありがとうございます!