【CSS/JavaScript】「iPhone iOS 背景固定 background-attachment:fixed ツールバー メニューバー 下 余白」でお困りの方へ
スマホだと background-attachment:fixed が使えないので、背景画像を固定する時に「::before」で代用するコードを良く見かけますね。
ただ、このあたりのコードをそのまま利用すると、iOSでスクロールする際に「メニューが隠れたり表示されたり」切り替わるタイミングで、下に変な余白ができてしまったり、background-size: cover; を設定しているとガクガクになったりします…。
結論としては、以下にすればOKです。
<script>
(function () {
//iOSのときのみ処理追加
if(isiPhone()) $('#fixed').css({height: screen.height});
})();
</script>
<style>
#fixed {
display: block;
position: fixed;
background: url(/img/bg_feature_summer.png) 50% 100% no-repeat;
background-size: cover;
top: 0;
left: 0;
width: 100%;
height: 120%;
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
z-index: -1;
}
</style>
<div id="fixed"></div>
transform を設定しないともスクロール中に変な余白が発生します。これを記載すると「描画をGPUが行うため解決できる」とのことで、おまじないのようなものです(笑)
これでも 「メニューが隠れたり表示されたり」 するタイミング(=リサイズ)で画面の高さが変わるため、height: 100%; と記載するだけでは下に余白が発生します。そのため height: 120% を設定しています。
ただ、リサイズのタイミングで背景画像がガクガクしちゃいます。仕方ないので、JSで予め screen.height で高さを指定しておくと違和感なくなりました。しかし、AndroidやiPad含めタブレット端末は、viewportの設定等の理由で devicePixelRatio の値が適切に取得できず、heightの設定が困難なので、取り急ぎiPhoneのみ対応しています。
追記:iPhoneのiOS11だと「もっと見る」後、imgタグが表示されない?
上記実装後、アコーディオンメニューのような「ボタンをタップしたあと中身を表示する」場合、iOS11のiPhoneだとコンテンツ内のimgタグがなぜか表示されません。
以下の状況が近いのかなと思います。
こちらの環境ではiPadでは再現せず、iPhoneのみの問題でした。取り急ぎの処置として、開いた後に一旦#fixedを非表示にし、すぐ再表示することで対応できました。
<style>
#moreArea {
display:none;
}
</style>
<div id="fixed"></div>
<div id="moreArea">
<img src="/img/img.png">
</div>
<button id="moreBotton">もっと見る</button>
<script>
$('#moreBotton').on('click', function () {
$('#moreArea').show();
//なぜかmoreArea内のimg.pngが表示されないので対応(iPhoneのみ)
if(isiPhone()) {
$('#fixed').hide();
setTimeout(function () { $('#fixed').show(); }, 10);
}
});
</script>