background:fixedでの背景固定はiOS(iPhone)でうまく動かないのでこれを使いましょう


自宅もちょっと作業がしやすい環境になってきて、休日でもブログを書けるようになってきました。
休日は仕事しないって決めてるんだけど、ちょっと空いた時間とかにこうやってブログ書けるのが良い。

iOSではbackground-attachment:fixed;が効かない!?

ちょっとおしゃれなホームページを作ってくれと言われたら、
簡単にできるものとして背景固定のパララックス風のページデザインがあります。
こんなやつです。

Frankie's Sports Bar & Grill

よくあるこんな感じの背景を固定して前面の要素だけが動くようなデザインですね。
シンプルだけど効果的な、このパララックスデザイン。
背景画像に
background-attachment:fixed;
とするだけで簡単に実装ができるだけれど、
実はこれ、iOSではうまく動かないんです。
具体的には、
background-attachment:fixed;
と合わせて、
background-size: cover
を同時に使った場合にうまく動きません。
パララックス風の背景固定をする場合、
background-size: cover
を同時に使になるので、実質的にこの方法ではダメということになります。
せっかく簡単にオシャレなページが作れると思ったんですが、レスポンシブが必須な今、iOSで使えない、つまりiPhoneでうまく機能しないのは非常に残念。
img
一番下に書かれていますね。
この方法では背景の固定ができないので、ちょっと無理矢理にテクニック的な形で同じような効果をiOSでも動くようにしてみましょう。

background-attachment:fixed;以外の方法で背景画像を固定する

なんとなくの説明はしますが、初心者の人には多少難しいかもしれない。
よくわからない人は、コピペでもして使ってもらったらと思います。、

background-attachment:fixed;を使わずにどうやって背景を固定するのかというと、
パララックスにしたい要素そのものに背景を固定しようとしてもできないので、
考え方としては、全画面を覆う背景を適用したブロック要素を作って、その要素自体をfixedで固定する。
つまり、背景画像を固定するのではなくて、位置を固定した要素をコンテンツの後ろに配置するという方法をとります。
要素という言葉だとわかりにくいかもしれないので、例えばdiv要素などと思えばいいでしょう。
「背景画像を固定する」と「要素自体を固定する」というこの違いわかりますかね。
この固定するための要素(例えばdivなど)を別で用意しないといけないんですけど、HTMLコードを触るのも面倒なのでCSSだけでやってしまいましょう。

今回は疑似要素というものを使います。
:beforeというものを使って、背景を指定しようとしていた要素の先頭にCSSによって要素を挿入します。
疑似要素についてはここでは説明しませんので、わからない人はそのままソースコードを覚えてください。
背景画像を設定しようとしていた要素に対して、先頭に疑似要素としてのブロック要素を挿入して。
つまり、簡単に言うとdivのようなものをCSSを使って挿入している感じです。
で、その挿入した疑似要素を、その背景ではなくそのものを固定します。
なので、ここではposition:fixedを使うんです。
widthはもちろん100%で、高さについては表示領域全体の高さということでvhという単位を使って100vhを指定。
vhっていう単位、かなり便利なんですがたぶん使ってる人少ないよね。

body:before{
  content:"";
  display:block;
  position:fixed;
  top:0;
  left:0;
  z-index:-1;
  width:100%;
  height:100vh;
  background:url(https://y-com.info/contents/wp-content/uploads/2017/05/IMG_1894.jpg) center no-repeat;
  background-size:cover;
}

こんな感じです。
例としてはbody要素に入れてますが、入れたいところに入れてください。
実際のデモはこちら。

See the Pen background fixed by Yoshimune (@hachidaime) on CodePen.

通常の背景をfixedした時と動き的には遜色ないでしょ(あたりまえですが)。

この問題は結構重要で、これ知らないで安易にパララックスで作りますよなんて言っちゃうと、iPhoneで見たときに動かなくって焦る
しかも簡単なパララックスならこれでいいけれど、ちょっと複雑になると今回の方法でも対処できないこともあって、
その場合はjQueryとかと組み合わせるしかなくなったりする。
という事例が自分自身が経験してて、その時の事例を出したかったけれどクライアントとの守秘義務の関係でここでは出せません。
出せたらいい事例だったんだけどな。
とりあえず、いざというときのために覚えておきましょうね。