iOS Safariでflex子要素のaspect-ratioが効かない:clip-path併用時に高さが正しく算出されない問題と解決策
iOS Safariで、aspect-ratioとwidthを指定した要素にclip-pathを併用すると、高さがアスペクト比どおりに算出されず、想定より大きくなる問題に遭遇しました。ChromeとFirefoxでは意図したとおりに表示される一方、検証した範囲で問題が再現したのはiOS Safariだけでした。
症状の近いWebKitの不具合には、Bug #265243があります。ただし、こちらはoverflowを指定したflex子要素を画面リサイズした際の問題です。本記事で扱うclip-pathを含む条件とは一致しません。
Bug #265243自体は2026年5月にWebKitで修正され、Safari Technology Preview 245のリリースノートにも掲載されました。WebKit側では解消済みですが、この修正を含まないSafariでは引き続き回避策が必要になります。
ここからは、問題が起きた条件を整理したうえで、height: autoでは解決しなかった理由と、aspect-ratioを使わない回避策を順に見ていきます。
再現条件
今回、問題が発生したのは次の組み合わせです。
- 親要素が
display: flex; flex-direction: column - 対象要素がflexコンテナの子要素であり、対象要素自身にも
display: flexが指定されている - 対象要素に
aspect-ratioと明示的なwidthが指定されている - 対象要素に
clip-pathが指定されている - 対象要素内の
imgなどにheight: 100%が指定されている
再現コード
<div class="parent"> <div class="child"> <img src="title.svg" alt=""> </div></div>
.parent { display: flex; flex-direction: column;}
.child { display: flex; align-items: center; aspect-ratio: 107 / 19; width: 107px; clip-path: rect(0 0 100% 0); /* アニメーション用 */}
.child img { width: 100%; height: 100%;}
期待される表示
幅は107px、アスペクト比は107 / 19。したがって、期待される高さは19pxです。
iOS Safariでの表示
iOS Safariでは高さが19pxを超え、想定したアスペクト比になりませんでした。同じコードをChromeとFirefoxで表示すると高さは19pxとなり、アスペクト比も維持されます。
条件別の検証結果
実装内で同じaspect-ratioのmixinを使う要素を、displayとclip-pathの組み合わせで整理すると次の結果になりました。
対象要素のdisplay | clip-path | 結果 |
|---|---|---|
flex | あり | 問題が発生 |
flex | なし | 正常 |
block | なし | 正常 |
block | あり | 未検証 |
検証した範囲では、問題が発生したのはdisplay: flexとclip-pathを併用した場合だけです。ただし、display: blockとclip-pathの組み合わせは検証していないため、clip-path単体の問題なのか、flexレイアウトとの組み合わせによるものなのかまでは切り分けられていません。
関連するWebKitの不具合
表示結果だけからWebKit内部の根本原因まで特定することはできません。一方、flexレイアウトやaspect-ratioに関する既知の不具合には、今回と近い症状の報告があります。
- Bug 265243 -
aspect-ratioCSS may not work correctly on a child of a flexbox — RESOLVED FIXED- Safari 17.1とiOS 17.0で、flex子要素に
overflowとaspect-ratioを指定し、画面をリサイズするとアスペクト比が維持されない問題として報告 - 2026年5月にWebKitで修正され、Safari Technology Preview 245のリリースノートにも掲載
- Safari 17.1とiOS 17.0で、flex子要素に
- Bug 231849 - Element with clip-path and aspect-ratio renders with wrong dimensions — RESOLVED DUPLICATE
clip-pathとaspect-ratioを併用した要素の表示サイズに関する過去の報告
- Bug 209983 - [css-flexbox] WebKit doesn't preserve aspect ratio when computing cross size of flexed images in auto-height flex container — RESOLVED FIXED
- flex子要素である画像のアスペクト比が保持されない過去の問題
Bug #265243では、画面をリサイズしたあともflex子要素の古い高さがキャッシュに残ることが原因でした。リサイズ後の高さが更新されない点は今回の症状と似ていますが、再現条件は別です。そのため同じ不具合とは断定せず、関連事例として捉えるのが妥当でしょう。また、修正を含むかどうかによって、Safariのバージョン間で挙動が異なる可能性もあります。
解決しなかった方法:height: autoの明示
まず試したのが、aspect-ratioを指定する要素へのheight: autoの追加です。widthとaspect-ratioから高さが改めて算出されることを期待し、mixinへ組み込みました。
// 今回の条件では解決しなかった@mixin aspect-ratio($number-a, $number-b) { $gcd: gcd($number-a, $number-b); $a: math.div($number-a, $gcd); $b: math.div($number-b, $gcd);
aspect-ratio: #{$a} / #{$b}; height: auto;}
ただし、heightの初期値はもともとautoです。今回の実装ではほかの高さを指定していなかったため、明示的に追加しても計算値は変わりません。iOS Safariでの表示にも変化はなく、この方法では解決に至りませんでした。
そのほかに考えられる回避策
回避の方向性としては、問題が発生する条件のいずれかを外す方法も考えられます。
- アニメーション要件が許せば、
clip-pathを使わない実装に変更する display: flexをdisplay: blockやdisplay: gridに変更する- 子要素の
height: 100%をheight: autoに変更する
いずれもレイアウトやアニメーションの変更を伴うため、そのまま置き換えられるとは限りません。採用できるかどうかは実装要件次第です。
採用した解決策:aspect-ratioを使わない
そこで採用したのが、CSSのaspect-ratioを削除し、imgのwidth属性とheight属性から得られるアスペクト比を使う方法です。
1. imgにwidth属性とheight属性を追加する
<!-- Before --><img src="title.svg" alt="タイトル">
<!-- After --><img src="title.svg" width="231" height="51" alt="タイトル">
2. CSSではwidthのみを指定する
// Before.c-section-title__ja { @include aspect-ratio(231, 51); width: rem(231);}
// After.c-section-title__ja { width: rem(231);}
3. imgの高さをautoにする
// Before.c-section-title img { width: 100%; height: 100%;}
// After.c-section-title img { width: 100%; height: auto;}
この方法で解決する理由
imgにwidth属性とheight属性があれば、ブラウザは画像を読み込む前でもアスペクト比を把握できる- CSSの
width: 100%; height: autoにより、表示幅に応じた高さが算出される - 問題が発生した要素でCSSの
aspect-ratioを使わないため、今回のSafariの挙動を回避できる
影響範囲
この問題は、aspect-ratioを使うすべての実装で起きるものではありません。今回顕在化したのは、flexレイアウト、clip-path、子要素のパーセント指定といった条件が重なったケースです。
加えて、関連するWebKitの修正が取り込まれているかどうかでも結果は変わります。Safariのバージョンをまたいで検証する場合は、この差も切り分けて考える必要があります。
まとめ
- iOS Safariでは、flex子要素で
aspect-ratioとclip-pathを併用した際に、高さが想定どおりにならない場合がある heightの初期値はautoであり、今回の実装ではheight: autoを明示しても表示は変わらなかった- 画像では、HTMLの
width属性とheight属性に加えて、CSSでheight: autoを指定する方法が有効だった width属性とheight属性の指定は、画像読み込み前のレイアウト領域を確保し、CLS(Cumulative Layout Shift)を抑えるうえでも役立つ- WebKit Bug #265243は2026年5月に修正済みだが、Safariのバージョンによっては回避策が必要になる
参考リンク
- WebKit Bug 265243 -
aspect-ratioCSS may not work correctly on a child of a flexbox - Safari Technology Preview 245 Release Notes
- WebKit Bug 231849 - Element with clip-path and aspect-ratio renders with wrong dimensions
- WebKit Bug 209983 - [css-flexbox] WebKit doesn't preserve aspect ratio when computing cross size of flexed images in auto-height flex container