2024/01/26

2024年、実用はまだちょっと待ったほうがいいCSS新仕様

技術系のブログで「使えるようになりました!」と書かれているものでも、世代によってアップデート可能なOSバージョンの上限があるiPhoneではまだまだ厳しいものが結構あるので注意されたし。

1. コンテナクエリはiPhone7以下でポリフィルが必要

任意の親要素のサイズを基準にして挙動を変えられる大変便利なコンテナクエリは、iOS16.0から対応。上限が15.8までのiPhone6/6s/6Plus/7/7plusで使えない。ただし共通JSファイルにでも書いておくだけで、変な副作用なく解決してくれる便利なポリフィルがあるのでそれを使えばOK。(詳しくはググればすぐ出てきますのでお願いします)

2. subgridはiPhone7以下で無効

親要素のグリッドを流用することで、高さ揃え系のJSで対処していた縦位置の統一が簡単にできるようになったsubgridも、iOS16.0から対応。上限が15.8までのiPhone6/6s/6Plus/7/7plusで使えない
しかしPCで横2~3カラムで配置していたカードをスマホでは幅100%で1カラムにしてしまう、というようなことは多いと思うので、気を付けて工夫すれば乗り切れそう。

3. 比較演算子を使ったメディアクエリはiPhone7以下で無効

(min-width:480px) and (max-width:767px) みたいなのが (480px <= width < 768px) と書けて嬉しいやつは、iOS16.4から対応。iPhone6/6s/6Plus/7/7plus(およびアップデートを怠けている後継機種)で使えない。これはJSの中に書いても同様に使えないので本当に注意。

4. 単位「cqw」はiPhone7以下で無効

vwではちょっと融通のきかなかった動的なサイズ変更もこれを使えば最強、なcqwもiOS16.4から対応。iPhone6/6s/6Plus/7/7plus(およびアップデートを怠けている後継機種)で使えない。バカでかくしたはずの見出し文字も1emで表示されたりして大問題。
デスクトップだとコンテンツエリアの最大幅よりもブラウザ幅を拡げることができて、vwよりcqwが便利だなあとなることが往々にしてあるのだけど、スマホではvw=コンテンツエリアの幅になるし、横方向にカラムを割るレイアウトをすることも少なかろうので、メディアクエリを絡めてうまく避ければ案外なんとかなる。

5. 単位「dvh」はiPhone7以下で無効

ブラウザが出したり引っ込めたりするボタンエリアやアドレスバーエリアの高さを差し引いた縦100%を一発で書ける、便利で有能なdvhもiOS16.4から対応。iPhone6/6s/6Plus/7/7plus(およびアップデートを怠けている後継機種)で使えない
これに関しては、縦が余分に長くなることで何らかのコントロールが隠れてしまうなど、致命的なユーザビリティのロスがなければ、「OS古い人は少々不格好になるけどゴメンなさい」で乗り切れなくもないことが多い気もする。

6. CSSネスティングはiPhone7以下で無効

これは使いたくて仕方ない人が多いであろう革新的なアップデートだけど、iOS16.5から対応。iPhone6/6s/6Plus/7/7plus(およびアップデートを怠けている後継機種)で使えない
個人的にはSCSSはカスってもいないため、まだまだ気長に待てる。おおっぴらに使えるようになったら楽だろうな~。そうなった暁には、BEMはちゃんと絶滅してもらいたい。

7. 「display:contents;」はiPhoneX以下で不完全

レスポンシブで複雑な組み換えをしたいときに重宝する、強制透明人間化命令ことdisplay:contentsは、iOS17台以前では部分的なサポートとなっている。
iOS15台以前およびAndroidのChromeでは、button要素に使用できないとの事だけど、buttonをdisplay:contents;にしたい気持ちにはなかなかならなそうだからまあ良いとする。
問題はiOS16台で、table系のロールを持つ要素に適用されないとの事(ちゃんとした詳細はCan I Useで確認されたし)。これは例えば、テーブルレイアウトで組まれた古いサイトを、HTMLは極力変えずにCSSだけで対処的にレスポンシブ化しましょうといった場合に、gridで自由な配置をするのに邪魔になるtbodyやtrを無視するのにまさにうってつけなはずのdisplay:table;が、それらの要素に対して使えないという非常にイヤな状況。iPhone6/6s/6Plus/7/7plus/8/8Plus/Xでダメ(XS、XRはセーフ)ということで、問題の起こるタグが限定的であるとはいえ、無視できない範囲が広い。

tbodyタグはHTMLに書いてなくてもDOM上で勝手に補われるので、記述しなきゃいいというわけにもいかない。運用中のサイトで発覚してしまい、大がかりな改修もすぐにはできなくて困り果て、ChatGPTをしばき倒してtableからtbodyだけを抜くJSを作ってもらった。(tbodyに何か意味のあることをやらせている場合は使えません)

<script>
document.addEventListener("DOMContentLoaded",()=>{
  Array.from(document.getElementsByTagName('table')).forEach(table=>{
    if(table.tBodies.length>0){
      const tbody=table.tBodies[0];
      while(tbody.firstChild)table.appendChild(tbody.firstChild);
      table.removeChild(tbody);
    }
  });
});
</script>

8. 追補

上記すべて、Xより後に出ているSE2はどれもセーフ。廉価ラインなのにありがたい。
また、最近ようやくFirefoxが折れて、めでたく全モダンブラウザ対応となったばかりの「:has()」は、スマホではiOS15.4から使えているため、早速本番使用して問題なさそう。この日をどんなに待ったことか。
あとは「+」や「~」の逆の直前要素、手前の兄弟要素のセレクタが使えるようになってくれたら本当に嬉しいのだが。

以上でした。