[css] flex-boxで使うimgタグの扱いがブラウザ毎に違う話

2020年11月6日

テクノロジー

eyecatch いい加減にブラウザ毎の挙動誤差にうんざりしている、下駄です。 便利機能は、どのブラウザも好きに付けてもらってもいいんですが、表示エンジンは統一してもらえないもんかな? 現時点におけるブラウザの定義はw3cでかなり厳密に決められているけど、それぞれのブラウザ毎の対応状況などは、まちまちな状態で、困るのは、開発者や利用するユーザーであることを考えると、業界の権利争いよりも、統制することの方が重要にも思えるんだけど・・・ と、文句を言っても始まらないので、問題を見つける度にブログに書くようにしているんですが、 カルーセル処理をライブラリなどを使わずに作っていたトコロ、"display:flex"で横並びの構成にしていて、スライドをimgタグにしていた際に、何故かsafariブラウザで、画像サイズが正常に表示されないという不具合を見つけ、その原因を調査した内容を公開しておきます。

ソースコード

使用する画像 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>flex-image-bug</title> <style> .slides{ display:flex; width:200px; scroll-snap-type: x mandatory; } .slide{ width:100%; scroll-snap-align: start; } </style> </head> <body> <div class="slides"> <img class="slide" src="image-1.jpg"> <img class="slide" src="image-2.jpg"> </div> </body> </html> これをGoogleChromeブラウザで表示すると・・・ safariブラウザで表示すると・・・ ナンテコッタ・・・

原因

調べてみたトコロ、原因はdisplay:flexであることがわかった。 コーディングした際のこちらの意図としては、flex-boxの内部画像は、画面幅に応じてwidthサイズが可変になるため、height要素は、auto(デフォルト)をセットして、自動的にサイズ変更して対応してもらうことを想定していて、 GoogleChromeブラウザでは、そのとおりに表示されて問題ないのですが、 Safariブラザザでは、flex-boxでセットされた内部画像は、height:autoの値が、width値を無視して、その画像のサイズがそのまま適用されてしまうようだ。 iPhoneでも同じ・・・ これは由々しき事態。

対処法

これを解決するには、いくつか方法が考えられるのだが、

解決法その1. flex-boxモードを使わない

display:flexの箇所を以下のようにすると、ある程度は解消できる。 display:inline-block; white-space:nowrap; でも、inline-block要素のため、コーディング時の改行などが無駄なスペースを発生させたりして、少し調整に手こずる可能性もある。

解決法その2. アスペクト比を固定する

この方法は、imgタグに対して、"object-fit:cover;"をセットする事で対応できるのだが、必ずheight値をセットしなくてはいけないという事になる。 "object-fit:contain;"にセットしたら、余白が出てしまう可能性もあるし、coverでは、トリミングされてしまう可能性もある。 GoogleChromeが、正常な見え方で有ることを考えると、なんとも妥協した対策になってしまう。

解決法その3. "align-self"プロパティを使う

どうやら、この方法が確実なようです。 "align-self: flex-start;"をimgタグにセットすると、height:auto;が有効になるようです。 GoogleChromeブラウザは、どうやら、この値がflexセットの時に自動で割り当てられるようですね。

最後に

こうした細かな挙動の差も、コーディングの時にかなり膨大な時間を有してしまうため、 こうしたデフォルト値の統一なども、今現在のWebブラウザに求められる重要な要素のような気がするのは、自分だけでしょうか? 誰かなんとかしれくれ!

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。