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: fixedinset: 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 による表示

See the Pen Fixed background for iOS by nov (@numerofive) on CodePen.

なんで、この方法を今まで気付けなかったんだろう。そして、background-attachmentプロパティの問題に関しては、なぜ「Appleは動かない」んでしょうかね。

関連記事