Chromeに実装された疑似クラス「:has()」がjQueryの「:has()」に悪影響、一定の条件下でWebサイトが壊れる可能性

今回は「Chromeに実装された疑似クラス「:has()」がjQueryの「:has()」に悪影響、一定の条件下でWebサイトが壊れる可能性」についてご紹介します。

関連ワード (中身、今月出、動向等) についても参考にしながら、ぜひ本記事について議論していってくださいね。

本記事は、Publickey様で掲載されている内容を参考にしておりますので、より詳しく内容を知りたい方は、ページ下の元記事リンクより参照ください。


最近リリースされたSafariとChromeで、CSSのSelectors Level 4(現時点でドラフト)仕様にある疑似クラス「:has()」が相次いで実装されました。

疑似クラス「:has()」は、カッコ内に要素を書くと、その要素を持つ親要素にのみ指定したスタイルを設定できる、という便利な機能を提供してくれます。

ところがこの「:has()」のChromeにおける実装は、jQueryで似たような機能(カッコ内の要素を持つ親要素を選択する)を提供する「:has()」に悪影響を及ぼし、このjQueryの「:has()」を使っているWebサイトでは、Chromeを利用した場合に一定の条件下でWebサイトが壊れるなどの問題を引き起こすことが分かりました(同じエンジンを利用しているMicrosoft Edgeも同様と思われます)。

これがどのような問題で、現時点でどのように解決されつつあるのかなどについて、Web標準の動向に詳しい矢倉眞隆氏が一連のツイートで解説していましたので、許可を得てツイートを転載します。

一連のツイートは2部に分かれています。前半ではChromeで問題が見つかり、その概要を把握するところ。後半は、より詳しい問題の中身と解決の方向性についてです。

まずは前半。

Chrome 105で`:has()`が入ったらjQueryが壊れたという話が出てきてうわーってなっている。https://t.co/HxjKvwpEwG

— Masataka Yakura (@myakura) September 3, 2022

jQueryは昔から`:has()`とか`:contains`みたいな拡張セレクタを持っている。`$()`とかで渡されるセレクタの処理はまず`querySelectorAll()`で処理して、処理できないものをjQuery側で受けるような仕組みだった。

— Masataka Yakura (@myakura) September 3, 2022

ただネイティブの`:has()`が入ったことで状況が変わる。名前がかぶるのもあるし、`:has()`の引数はforgiving selector listという、invalidなセレクタがあっても全部が落ちないように処理するようになっている。結果拡張セレクタがjQueryに渡されなくなってしまうことに。

— Masataka Yakura (@myakura) September 3, 2022

で、WebKitでも`:has()`の実装が入っているが、いいのか悪いのかセレクタの処理が違っていたため壊れていないらしい。ChromeもこのWebKitの挙動を導入して回避しようとしているが、それで全部解決するか……?

— Masataka Yakura (@myakura) September 3, 2022

あー、「壊れた」だけだと言葉不足かな。jQueryを使ったコードすべてに影響はしなくて、`ul:has(li:contains('Item'))`みたいにjQueryの拡張セレクタを`:has()`内で使っていたら問題になる。

— Masataka Yakura (@myakura) September 3, 2022

ChromeもWebKitの挙動をワークアラウンドとして実装。中に書かれたセレクタがすべて通らなかったな場合にinvalidになる。
Canaryではもう入っていて、Stableもrespinがかかったのでそれの展開待ち。105リリース直後でそのビルドさえ100%展開されてないはずだけど、この場合どうなるんだろうな。

— Masataka Yakura (@myakura) September 5, 2022

このワークアラウンドも一部のケースにしか対応できないので、ほんと一時しのぎといった感じ。仕様での解決をしないといけないけど、どうするんだろうな……

— Masataka Yakura (@myakura) September 5, 2022

あとはiOS 16もおそらく今月出ると思うんだけどどうするんだろう。

— Masataka Yakura (@myakura) September 5, 2022

ここまでが前半です。

後半では、問題を解決しようとしているChromeとjQueryの状況、より詳しい発生条件、そして今後の見通しなど。

Chromeの`:has()`とjQueryのやつ。その後どうなっているか。https://t.co/4T4omotAtn

— Masataka Yakura (@myakura) September 14, 2022

まずブラウザ。Chromeが緩和策としてWebKitの実装(バグ)をコピー。壊れるケースは多少減るはずだが、まだリリースにのってない。

WebKitは今週Safari 16がリリースされたので、`:has()`がリリースされてしまった。jQueryは壊れないが、仕様からはずれている実装。

— Masataka Yakura (@myakura) September 14, 2022

jQueryは引数にとるセレクタをチェックする実装を追加しようとしている。こちらもまだリリースされていない。リリースされたとしても古いバージョンへの対策にはならないので、今後の互換性を確保するという側面が強い。https://t.co/Sh0jmy7CK3

— Masataka Yakura (@myakura) September 14, 2022

あと、チェックするのに使うブラウザのAPI(`CSS.supports(selector())`)が更新されないといけないが、これも未リリース。Chromeは107で対応するらしいが、バックポートはしない感じ(何でだろう)。

— Masataka Yakura (@myakura) September 14, 2022

で、CSSの仕様はどうなるか。

ChromeとWebKitの実装はじきに揃うが、これはちょっとバグってたWebKitの挙動が今回の問題にたまたま効果があったから採用したというやつで、仕様から外れてしまっている状態。

— Masataka Yakura (@myakura) September 14, 2022

WebKitの挙動を仕様にしたとしても問題に完全に対応できるわけではないし、いびつな条件分岐が入ってしまってうれしくない。

— Masataka Yakura (@myakura) September 14, 2022

仕様をどうするかは、ちょうど今週CSSWGの会議があるので、そこで話される予定。Safariもリリースされてしまったので、`:has()`の名前を変えるとか、引数のセレクタリストの解釈を変えるとかはしにくい状況になったのではないかな。どうするんだろうな……

— Masataka Yakura (@myakura) September 14, 2022

そうそう、影響範囲はどんなものか。こないだは`:has(:contains())`みたいに、jQuery独自のセレクタが`:has()`内で使われている時だけ起こっているっぽいと書いたんだけど、どうやらそれだけだと充分ではなさそう。

— Masataka Yakura (@myakura) September 14, 2022

jQueryの拡張セレクタを使っていないくても、jQueryは通すがCSS仕様としては通らない書き方に依存したコードだと問題になる。
具体的に見つかってるものとして、`:has()`のネストと、属性セレクタの値の書き方がある。

— Masataka Yakura (@myakura) September 14, 2022

CSSの仕様だと`:has()`は今のところネストできない。実装の複雑さを避ける目的なんだけど、jQueryではネストできてしまう。Chromeに報告された、実際に壊れたサイトではこのネストした`:has()`が使われていた。https://t.co/ULn7PnMP3x

— Masataka Yakura (@myakura) September 14, 2022

属性セレクタの値というのは、`[foo=1]`のように、属性値がクオートで囲まれておらず、かつ数値で始まっているもの。CSSでは値が数値で始まる場合にはクオートが必要なんだけど、どうやらjQueryは属性セレクタの値の解釈が厳密ではなかったみたい。https://t.co/LTZ6SLwHKj

— Masataka Yakura (@myakura) September 14, 2022

それ以外にどんなセレクタが影響するかはちょっとわからないので、確かめたほうがはやそう。Chrome 107(今はCanary)でコンソールでも開いて、`CSS.supports('selector(セレクタ)')`と打てばよいかな。

— Masataka Yakura (@myakura) September 14, 2022

あ、そうだ。jQueryを使ったサイトやアプリ以外でも問題が報告されている。
Cypressは一部メソッドで要素を取ってくる手段にjQueryを使っているらしく、そこで`:has()`を使っていたりすると問題が出る。https://t.co/u2v6i2Pb3X

テストフレームワークは確かに。要素とってくる時に使いたくなるよな。

— Masataka Yakura (@myakura) September 14, 2022

これは憶測だけど、ブラウザの拡張とかで地味に壊れているやつあるんじゃないかなあ。コンテントスクリプトからページのDOMにアクセスするときにjQuery使うケースはありそう。歴史のある拡張とかだと特に。

— Masataka Yakura (@myakura) September 14, 2022

さてCSSWGのミーティングがあり、この話題も取り上げられたんだが……仕様をどうにも変えていきにくいのとまだ影響がどれくらいか分からないということで、「注視していきたい」的な感じで終わってしまった。うーむhttps://t.co/flc1GChUFX

— Masataka Yakura (@myakura) September 18, 2022

`:has()`っていう名前をあきらめたくないのはまあわかるんだが、名前変える以外でちゃんとした解決はできないと思うなー

— Masataka Yakura (@myakura) September 18, 2022

いろいろ不幸なんだよな。

・Chromiumの実装がフラグ単体で無効にできるようになってなかったらしく、コードでのrevertが必要だった
・WebKitがちょっとバグってて、その挙動がたまたま今回の問題に多少効果的だった

なのでWebKitに合わせられてしまって、そして問題をぼんやりさせてしまった感じ

— Masataka Yakura (@myakura) September 18, 2022

あとは広報的なところでも

・渇望されていた機能で、リリース前からいろんなところで盛り上げていた
・Safariのリリースも直前だった

という、簡単にrevertできたとしてもそれがやりにくい雰囲気というのがな

— Masataka Yakura (@myakura) September 18, 2022

この問題に遭遇するケースはそれほど多くないとは思いますが、Webサイトの制作関連の仕事をしている方は動向に注意された方がよいかもしれません。

COMMENTS


Recommended

TITLE
CATEGORY
DATE
【3月1日】掲載記事アクセスランキング・トップ5―1位はウクライナ侵攻への経済制裁によりロシア国内でApple Pay利用停止
IT関連
2022-03-02 00:20
フィットネスクラブ・スクールなど店舗向け会員管理・予約・決済システム「hacomono」が5億円調達
ネットサービス
2021-03-23 16:40
大手ECなどかたるフィッシングメール、1年で5倍に 被害に遭わないためには?
くわしく
2021-02-19 23:45
ITプロフェッショナルがキャリアを磨くために今必要なこと–ボーイングのCIOに聞く
IT関連
2022-04-02 13:44
稲畑産業、インテル「RealSense」代替品となる3Dセンサー「LIPSedge」シリーズを発売へ―台湾LIPSが開発
IT関連
2022-03-05 00:50
アテネのベンチャーキャピタル集まれ:TechCrunchヨーロッパVC大調査の結果レポートに載ろう
VC / エンジェル
2021-01-21 21:53
【レビュー】成熟した市場に参入する低価格の変わり種、Nothingのワイヤレスイヤフォン「Ear(1)」
ハードウェア
2021-08-05 07:14
NEC、「スポーツビジネス推進本部」を新設–企業スポーツのビジネス化を加速
IT関連
2021-07-20 01:05
Redditが人知れずiOSアプリにTikTokのようなビデオ機能を実装
IT関連
2021-08-15 00:38
ヤオコー、経費精算クラウドSaaSの導入で年間5万枚の領収書をデジタル化
IT関連
2023-11-30 13:49
【コラム】アニメーター、ライター、デザイナーに朗報、活気ある米国のゲーム業界にはチャンスが溢れている
ゲーム / eSports
2021-06-01 02:43
AWS、VSCodeからAmazon Redshiftのスキーマオブジェクトの表示やクエリの実行を可能にする「Amazon Redshift integration with Visual Studio Code」提供開始
AWS
2023-10-20 02:44
国内企業のDevOps実践率は59.3%に上昇–IDC調査
IT関連
2023-01-12 00:32
全自動除草ロボット・サービスのFarmWiseが薬物散布機能を追加
IT関連
2021-02-25 01:29