background-attachment:fixedが効かない問題の最終解決策
「背景画像は動かない」を実現する background-attachment: fixed
ですが、Apple製品では機能しないという重大な問題があります。今回は、この問題のファイナルアンサーを紹介します。
以前、「background-attachment:fixedが効かないブラウザ用パララックス」という記事を書いたのですが、この時は position: sticky
を使用して background-attachment: fixed
っぽいことを実現していました。
今回は、background-attachment: fixed
と全く同じように振舞わせる方法となります。
サンプルのHTML
<div class="__bg__dot">
<p> … </p>
</div>
<div class="__bg__check">
<p> … </p>
</div>
<div class="__bg__grid">
<p> … </p>
</div>
<div class="__bg__stripe">
<p> … </p>
</div>
背景画像を固定したdiv要素の中にp要素があるという、非常にシンプルな構造です。
HTMLに適用するCSS
[class*="__bg__"] {
display: flow-root;
min-height: 100vh;
}
[class*="__bg__"]::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
}
.__bg__dot::before {
background:
linear-gradient(45deg, #c0c0c0 25%, transparent 25%) 0 0 / 16px 16px,
linear-gradient(225deg, #c0c0c0 25%, transparent 25%) 8px 8px / 16px 16px;
}
.__bg__check::before {
background:
linear-gradient(45deg, #c0c0c0 25%, transparent 25%, transparent 75%, #c0c0c0 75%) 0 0 / 16px 16px,
linear-gradient(45deg, #c0c0c0 25%, transparent 25%, transparent 75%, #c0c0c0 75%) 8px 8px / 16px 16px;
}
.__bg__grid::before {
background:
linear-gradient(0deg, #c0c0c0 50%, transparent 50%) 0 0 / 16px 16px,
linear-gradient(90deg, transparent 50%, #c0c0c0 50%) 0 0 / 16px 16px;
}
.__bg__stripe::before {
background:
repeating-linear-gradient(0deg, #c0c0c0, #c0c0c0 8px, transparent 8px, transparent 16px);
}
まず、擬似要素に背景画像を設定し、position: fixed
と inset: 0
で固定して、z-index: -1
で背面に配置します。
ここまでは、既に多くのサイトで紹介されています。この方法の欠点は、固定する背景画像を1つしか設定できないこと、もう1つは、固定した背景画像を背面に表示したくない要素には、背景色などを設定して覆い隠す必要があるということです。
背景画像を固定したい、ただそれだけのために、多くの労力を費やす必要がありました。でも、擬似要素の親要素に clip-path: inset(0)
を追加するだけで、全て解決します。
[class*="__bg__"] {
clip-path: inset(0);
display: flow-root;
min-height: 100vh;
}
clip-pathプロパティは要素のクリッピング領域 (表示領域と非表示領域) を設定するプロパティです。固定された擬似要素は、親要素の表示領域でのみ表示されるようになるため、background-attachment: fixed
と全く同じ挙動になるという訳です。
CodePen による表示
〆
なんで、この方法を今まで気付けなかったんだろう。そして、background-attachmentプロパティの問題に関しては、なぜ「Appleは動かない」んでしょうかね。