iOS Safari(おそらく14系)のページ表示不具合と対応まとめ

2022年6月にIEのサポートが終了しましたが、Safariで想定外の表示になっていることがあります。

iPhoneSafari(おそらくバージョンは14)で表示が変、というお声を頂いたことをきっかけに、色々調べました。

対応表を書いてくださった記事がありましたので載せさせていただきます。

iOSのバージョンと Safariバージョンの対応表(2022/10/6 現在 - Qiita

※記事タイトルの「系」の使い方。Safariのバージョン14.0〜14.1.2のことをまとめて言いたいのですが、あっているといいな...。

☆以降の「Safari」はiPhoneのSafari14系で起こったことと想定して下さい。

CSSグラデーションで transparent を使うと黒くなる

対応策:transparent の代わりに rgba() を使って色指定まで行う

linear-gradient() 関数を使って背景色にグラデーションをかけることがありますが、「透明」を指定する際に transparent を使うと、Safariでは黒くなってしまいます。

例)赤から透明になるグラデーション

div {
  background: linear-gradient(#e66465, transparent);
}

Safariではグラデーションが上から下にかけて
赤→黒→透明
になります。

Appleデバイスでtransparentのグラデーションが黒くなる現象 | 無題のブログ

W3Cの仕様書だと transparent は rgba(0, 0, 0, 0) のショートハンドと定義さております。

rgba(0, 0, 0, 0) は「透明な黒」です。
ransparentの実態が分かり目からうろこでした。

以下のように書くと、Safariでも黒が入らず単色の透明グラデーションになりました。

div {
  background: llinear-gradient(#e66465, rgba(230, 100, 101, 0));
}

#e66465 という16進数(HEX:Hexadecimal)のカラーコードをRGBに変換して、さらにアルファ(a)を0、すなわち透明にした数値を rgba() 関数に設定します。

上のコードはHEXとRGB両方使われていて気持ち悪いので
llinear-gradient(rgba(230, 100, 101, 1), rgba(230, 100, 101, 0)) がいいと思います。

そこで今度はなぜChromeなどのブラウザでは rgba(0, 0, 0, 0) を使っても黒くならないのか気になりました。

記事には

グラデーションの計算は乗算済みアルファ

と、Chromeなどでのブラウザではアルファは「乗算済み」のため透明になるようです。
が、参考記事の参考記事を見ても「乗算済みアルファ」が分からなかったので、そういうことなのかとぼんやり理解することにします。

なのでChromeなどではアルファ(透明度)の値が0であれば、何色の透明であってもその色が間に表示されることはなく、透明グラデーションが表示されます。

色を変化させつつ、だんだん透明にするグラデーションを作る場合は難しいなと思いました。

Photoshopのグラデーションのように、色と透明度の軸が別々の書き方がもしかしたらあるのかもしれません。

CSS グラデーション ジェネレーターを見た限りではできなさそうでした。

フォトショのようにグラデーションを描画したい時のイメージです。

水色からピンクへ、次第に透明になるグラデーションです(不透明度0%→100%)。
CSSの場合は、水色とピンクの中間にポイントを取って、中間色・中間の透明度を指定すると、それっぽくなりました。
透明になるピンクのポイントは「ピンクの透明」でなくても透明であれば何色でもよい、というのが変な感じです。

transparentは極力使わないほうが無難ですね。

Webpは表示されない

対応策:webpが表示されない場合の代替画像の記述をしておく

Webpは「ウェッピー」と呼びます。
心の中で1回「ウェブピー」と言っています。

Webp非対応は2022年11月現在IEぐらいなので、もっと積極的に使っていきたいです。
(今調べるとSafari on iOSの14以降も対応しているみたいですが、非表示だったのは何だったのだろう...)

もう悩まない。Mac版safariも対応したのでWebP始めました | ホームページ制作 | 茨城県水戸市 | 株式会社グレイズ

保険としてjpeg画像が表示されるようにpictureタグとsourceタグを使って書きます。

<picture>
 <source srcset="img/webp-image.webp" type="image/webp">
 <img src="img/jpeg-image.jpg" alt="イメージ">
</picture>

Photoshopではプラグインを使ってWebpが書き出せるのですね!
早く標準で書き出せるようになってほしいです。

cssプロパティ aspect-ratio が使えない

対応策:従来の方法(padding-topなど)

縦横比を指定できる便利な aspect-ratio ですが、使えるはのSafari15からだそうです。

"aspect-ratio" | Can I use... Support tables for HTML5, CSS3, etc

表示が崩れてしまった方にアップデートしてくださいって言いたい...!

aspect-ratio については以前調べました。こちらです。

***

ここからはiOSであった問題と対策です。

番外:スクロール禁止に使っていた preventDefault() が理想通りに動かず

iOS対策のためにグローバルメニューを開いたときにページスクロールを止めるために入れていました。 しかしメニュー内のスクロールもできなくなってしまうので使うのを止めました。

iOS でページ全体はスクロールを無効にし、個別の要素(textarea など)では有効にする方法

window.addEventListener('touchmove', function(event) {
    event.preventDefault();
});

これだとすべてのスクロールイベントを発生させないように指定してしまいます。

preventDefault() のそもそもを下記で学んでから、上記記事のコードを解読して、組み込んでみたいと思います。

JavaScriptのpreventDefault()って難しくない?preventDefault()を使うための前提知識 - Qiita

番外:アドレスバーなどで height: 100vh だとはみ出てしまう問題

iOSでも100vhをいい具合に調整して画面の高さいっぱいに要素を表示させる

Javascriptで高さを取得して、cssに変数を設定するという技です。

const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);

ウィンドウサイズの高さ1vhあたりのpxを変数vhに格納して、setProperty()
--vh: ${vh}pxcssにセットしています。

100vhというのはiPhone Safariだけではなく色々なブラウザでもはみ出そうなので使っていきたいです!

さいごに

バージョンアップの中でも、大幅に変更のある壁が存在するのだなぁとしみじみ思いました。

バージョン違いで使える・使えないはあるあるなので、バージョンを意識しながら新しい記事を見るようにします!

おしまい。