Houdini:たぶんあなたが聞いたことがないCSSの最もエキサイティングな開発
公開: 2022-03-10特定のCSS機能を使用したいと思ったことがありますが、すべてのブラウザーで完全にサポートされていなかったために使用しませんでしたか? または、さらに悪いことに、それはすべてのブラウザでサポートされていましたが、サポートはバグがあり、一貫性がなく、完全に互換性がありませんでしたか? もしこれがあなたに起こったなら—そして私はそれが起こったに違いない—それならあなたはフーディーニを気にかけるべきです。
Houdiniは新しいW3Cタスクフォースであり、その最終的な目標はこの問題を永遠に解消することです。 これを実現するために、開発者にCSS自体を拡張する機能と、ブラウザーのレンダリングエンジンのスタイリングおよびレイアウトプロセスにフックするツールを初めて提供する新しいAPIセットを導入する予定です。
SmashingMagの詳細:
- WebDev環境のローカルインストールを停止する必要がある理由
- CSSの未来:実験的なCSSプロパティ
- 53CSS-なしでは生きていけないテクニック
しかし、具体的にはどういう意味ですか? それもいい考えですか? そして、それは私たちの開発者が現在そして将来ウェブサイトを構築するのにどのように役立つでしょうか?
この記事では、これらの質問に答えようとします。 しかし、その前に、今日の問題が何であるか、そしてなぜそのような変更の必要性があるのかを明確にすることが重要です。 次に、Houdiniがこれらの問題をどのように解決するかについてより具体的に説明し、現在開発中のよりエキサイティングな機能のいくつかをリストします。 最後に、Houdiniを実現するために、Web開発者として今日できる具体的なことをいくつか紹介します。
Houdiniが解決しようとしている問題は何ですか?
記事を書いたり、新しいCSS機能を紹介するデモを作成したりするときはいつでも、必然的にコメントやTwitterの誰かが次のように言うでしょう。 残念ながら、今後10年間は使用できなくなります。」
このようなコメントが迷惑で非建設的であるように、私は感情を理解しています。 歴史的に、機能の提案が広く採用されるまでには何年もかかりました。 その理由は、Webの歴史を通じて、CSSに新しい機能を追加する唯一の方法は標準化プロセスを経ることだったからです。

私は標準化プロセスにまったく反対していませんが、それが長い時間がかかる可能性があることは否定できません!
たとえば、フレックスボックスは2009年に最初に提案されましたが、開発者は、ブラウザのサポートが不足しているため、現在でもフレックスボックスを使用できないと不満を漏らしています。 確かに、最近のほとんどすべてのブラウザが自動的に更新されるようになったため、この問題は徐々に解消されています。 しかし、最新のブラウザを使用しても、提案と機能の一般提供の間には常に遅れがあります。
興味深いことに、これはWebのすべての領域に当てはまるわけではありません。 JavaScriptで最近どのように機能しているかを考えてみましょう。

このシナリオでは、アイデアを持ってから本番環境で使用できるようになるまでの時間は、数日かかる場合があります。 つまり、私はすでに本番環境でasync
/ await
関数を使用しており、その機能は1つのブラウザーにも実装されていません。
また、これら2つのコミュニティの一般的な感情にも大きな違いが見られます。 JavaScriptコミュニティでは、物事の動きが速すぎると人々が不満を言う記事を読んでいます。 一方、CSSでは、実際に使用できるようになるまでに時間がかかるため、新しいことを学ぶことの無益さを嘆く人々がいます。
では、CSSポリフィルをもっと書いてみませんか?
最初は、CSSポリフィルをもっと書くことが答えのように思えるかもしれません。 優れたポリフィルがあれば、CSSはJavaScriptと同じくらい速く動くことができますよね?
悲しいことに、それはそれほど単純ではありません。 CSSのポリフィルは非常に難しく、ほとんどの場合、パフォーマンスを完全に損なうことのない方法で行うことは不可能です。
JavaScriptは動的言語です。つまり、JavaScriptを使用してJavaScriptをポリフィルすることができます。 そしてそれはとてもダイナミックなので、それは非常に拡張可能です。 一方、CSSをCSSのポリフィルに使用することはめったにありません。 場合によっては、ビルドステップでCSSをCSSにトランスパイルできます(PostCSSがこれを行います)。 ただし、DOMの構造や要素のレイアウトや位置に依存するものをポリフィルする場合は、ポリフィルのロジックをクライアント側で実行する必要があります。
残念ながら、ブラウザはこれを簡単にしません。
次のグラフは、ブラウザがHTMLドキュメントを受信してから画面にピクセルを表示するまでの基本的な概要を示しています。 青い色のステップは、JavaScriptが結果を制御する力を持っている場所を示しています。

写真はかなり暗いです。 開発者は、ブラウザがHTMLとCSSを解析し、それをDOMとCSSオブジェクトモデル(CSSOM)に変換する方法を制御できません。 カスケードを制御することはできません。 ブラウザがDOM内の要素のレイアウトを選択する方法や、それらの要素を画面上に視覚的に描画する方法を制御することはできません。 そして、あなたはコンポジターが何をするかを制御することはできません。
フルアクセスできるプロセスの唯一の部分はDOMです。 CSSOMはややオープンです。 ただし、Houdini Webサイトを引用すると、「指定が不十分で、ブラウザー間で一貫性がなく、重要な機能が欠落しています」。
たとえば、今日のブラウザのCSSOMは、クロスオリジンスタイルシートのルールを表示せず、理解できないCSSルールまたは宣言を破棄するだけです。つまり、ブラウザの機能をポリフィルする場合は、それはそれをサポートしていません、あなたはCSSOMを使うことができません。 代わりに、DOMを調べて、 <style>
タグや<link rel=“stylesheet”>
タグを見つけ、CSSを自分で取得し、解析して書き直してから、DOMに追加し直す必要があります。
もちろん、DOMを更新するということは、通常、ブラウザーがカスケード、レイアウト、ペイント、および合成のステップ全体をもう一度やり直す必要があることを意味します。

ページを完全に再レンダリングする必要があることは、パフォーマンスにそれほど大きな影響を与えないように見えるかもしれませんが(特に一部のWebサイトでは)、これが発生する可能性のある頻度を考慮してください。 スクロールイベント、ウィンドウのサイズ変更、マウスの動き、キーボードイベントなどに応じてポリフィルのロジックを実行する必要がある場合、実際にはいつでも変更が加えられると、状況は著しく遅くなり、場合によってはひどく遅くなります。
今日のほとんどのCSSポリフィルには、独自のCSSパーサーと独自のカスケードロジックが含まれていることに気付くと、これはさらに悪化します。 また、解析とカスケードは実際には非常に複雑なものであるため、これらのポリフィルは通常、大きすぎるか、バグが多すぎます。
私が今言ったすべてをより簡潔に要約すると、ブラウザが想定していることとは異なることを実行したい場合(CSSを指定した場合)、更新および変更して偽造する方法を見つけ出す必要がありますDOMを自分で。 レンダリングパイプラインの他のステップにアクセスすることはできません。
しかし、なぜブラウザの内部レンダリングエンジンを変更したいのでしょうか。
これは、私にとって、この記事全体で答える最も重要な質問です。 したがって、これまでスキミングを行ってきた場合は、この部分をゆっくりと注意深く読んでください。
最後のセクションを見た後、あなた方の何人かは「これは必要ない! 通常のWebページを作成しているだけです。 私はブラウザの内部をハッキングしたり、超豪華な、実験的な、または最先端の何かを構築しようとはしていません。」
あなたがそれを考えているなら、私はあなたに少し戻って、あなたが何年にもわたってウェブサイトを構築するために使ってきた技術を本当に調べることを強く勧めます。 ブラウザのスタイリングプロセスにアクセスしてフックすることは、派手なデモを作成することだけではありません。開発者とフレームワークの作成者に2つの主要なことを実行する力を与えることです。
- クロスブラウザの違いを正規化するには、
- 人々が今日それらを使用できるように、新しい機能を発明またはポリフィルすること。
jQueryなどのJavaScriptライブラリを使用したことがある場合は、この機能の恩恵を受けています。 実際、これは今日のほとんどすべてのフロントエンドライブラリとフレームワークの主なセールスポイントの1つです。 GitHubで最も人気のある5つのJavaScriptおよびDOMリポジトリ(AngularJS、D3、jQuery、React、Ember)はすべて、ブラウザー間の違いを正規化するために多くの作業を行うため、それについて考える必要はありません。 それぞれが単一のAPIを公開し、それは機能します。
ここで、CSSとそのすべてのクロスブラウザーの問題について考えてみましょう。 クロスブラウザの互換性を主張するBootstrapやFoundationなどの人気のあるCSSフレームワークでさえ、実際にはクロスブラウザのバグを正規化せず、単にそれらを回避します。 また、CSSのクロスブラウザのバグは、過去のものではありません。 今日でも、フレックスボックスなどの新しいレイアウトモジュールでは、多くのクロスブラウザの非互換性に直面しています。
肝心なのは、CSSプロパティを使用して、すべてのブラウザーでまったく同じように機能することを確認できれば、開発期間がどれほど良くなるか想像してみてください。 また、ブログの投稿で読んだり、会議や交流会で聞いたりするすべての新機能について考えてみてください。CSSグリッド、CSSスナップポイント、スティッキーポジショニングなどです。 今日、それらすべてをネイティブCSS機能と同じくらいパフォーマンスの高い方法で使用できると想像してみてください。 そして、あなたがする必要があるのは、GitHubからコードを取得することだけです。

これがフーディーニの夢です。 これは、タスクフォースが可能にしようとしている未来です。
したがって、CSSポリフィルを作成したり、実験的な機能を開発したりする予定がない場合でも、他の人が作成できるようにしたいと思うでしょう。これらのポリフィルが存在すると、誰もがその恩恵を受けるからです。
現在開発中のHoudiniの機能は何ですか?
開発者はブラウザのレンダリングパイプラインへのアクセスポイントをほとんど持っていないことを前述しました。 実際、唯一の場所はDOMと、ある程度はCSSOMです。
この問題を解決するために、Houdiniタスクフォースは、開発者がレンダリングパイプラインの他の部分にアクセスできるようにするいくつかの新しい仕様を導入しました。 次のグラフは、パイプラインと、どの新しい仕様を使用してどのステップを変更できるかを示しています。 (灰色の仕様は計画されていますが、まだ書かれていないことに注意してください。)

次のいくつかのセクションでは、それぞれの新しい仕様と、それが提供する機能の種類について簡単に説明します。 また、この記事では他の仕様については触れられていないことに注意してください。 完全なリストについては、HoudiniのドラフトのGitHubリポジトリを参照してください。
CSSパーサーAPI
CSSパーサーAPIは現在作成されていません。 したがって、私が言うことの多くは簡単に変更できますが、基本的な考え方は、開発者がCSSパーサーを拡張して、新しい構成(たとえば、新しいメディアルール、新しい疑似クラス、ネスト、@ @extends
、 @apply
)について伝えることができるということです。 @apply
など。
パーサーがこれらの新しい構成を認識すると、それらを単に破棄するのではなく、CSSOMの適切な場所に配置できます。
CSSプロパティと値API
CSSにはすでにカスタムプロパティがあり、前に述べたように、CSSが解き放つ可能性に非常に興奮しています。 CSSプロパティと値APIは、カスタムプロパティをさらに一歩進め、タイプを追加することでさらに便利にします。
カスタムプロパティに型を追加することには多くの優れた点がありますが、おそらく最大のセールスポイントは、開発者がカスタムプロパティを移行およびアニメーション化できるようになることです。これは、現在は不可能です。
この例を考えてみましょう。
body { --primary-theme-color: tomato; transition: --primary-theme-color 1s ease-in-out; } body.night-theme { --primary-theme-color: darkred; }
上記のコードでは、 night-theme
クラスが<body>
要素に追加されると、 –primary-theme-color
プロパティ値を参照するページ上のすべての要素がtomato
からdarkred
にゆっくりと移行します。 今日これを実行したい場合は、プロパティ自体を遷移させることはできないため、これらの各要素の遷移を手動で記述する必要があります。
このAPIのもう1つの有望な機能は、「適用フック」を登録する機能です。これにより、開発者は、カスケードステップの完了後に、要素のカスタムプロパティの最終値を変更できます。これは、ポリフィルにとって非常に便利な機能です。
CSSタイプのOM
CSS Typed OMは、現在のCSSOMのバージョン2と考えることができます。 その目標は、現在のモデルの多くの問題を解決し、新しいCSS解析APIとCSSプロパティおよび値APIによって追加された機能を含めることです。
Typed OMのもう1つの主要な目標は、パフォーマンスを向上させることです。 現在のCSSOMの文字列値を意味のある型のJavaScript表現に変換すると、パフォーマンスが大幅に向上します。
CSSレイアウトAPI
CSS Layout APIを使用すると、開発者は独自のレイアウトモジュールを作成できます。 また、「レイアウトモジュール」とは、CSSのdisplay
プロパティに渡すことができるすべてのものを意味します。 これにより、開発者は初めて、 display: flex
やdisplay: table
などのネイティブレイアウトモジュールと同じくらいパフォーマンスの高いレイアウトを行うことができます。
ユースケースの例として、Masonryレイアウトライブラリは、CSSだけでは不可能な複雑なレイアウトを実現するために開発者が今日進んでいく範囲を示しています。 これらのレイアウトは印象的ですが、残念ながら、特にパフォーマンスの低いデバイスでは、パフォーマンスの問題が発生します。
CSS Layout APIは、レイアウト名(後でCSSで使用される)を受け入れるregisterLayout
メソッドと、すべてのレイアウトロジックを含むJavaScriptクラスを開発者に提供することで機能します。 これは、 registerLayout
を介してmasonry
を定義する方法の基本的な例です。
registerLayout('masonry', class { static get inputProperties() { return ['width', 'height'] } static get childrenInputProperties() { return ['x', 'y', 'position'] } layout(children, constraintSpace, styleMap, breakToken) { // Layout logic goes here. } }
上記の例で意味がない場合でも、心配する必要はありません。 気にする主なことは、次の例のコードです。 masonry.js
ファイルをダウンロードしてWebサイトに追加すると、次のようにCSSを記述でき、すべてが正常に機能します。
body { display: layout('masonry'); }
CSSペイントAPI
CSS Paint APIは、上記のLayoutAPIと非常によく似ています。 これは、 registerPaint
メソッドと同じように動作するregisterLayout
メソッドを提供します。 開発者は、CSSイメージが期待される場所であればどこでもCSSのpaint()
関数を使用して、登録された名前を渡すことができます。
これは、色付きの円を描く簡単な例です。
registerPaint('circle', class { static get inputProperties() { return ['--circle-color']; } paint(ctx, geom, properties) { // Change the fill color. const color = properties.get('--circle-color'); ctx.fillStyle = color; // Determine the center point and radius. const x = geom.width / 2; const y = geom.height / 2; const radius = Math.min(x, y); // Draw the circle \o/ ctx.beginPath(); ctx.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.fill(); } });
そしてそれはこのようにCSSで使用することができます:
.bubble { --circle-color: blue; background-image: paint('circle'); }
これで、 .bubble
要素が青い円を背景として表示されます。 円は中央に配置され、要素自体と同じサイズになります。
ワークレット
上記の仕様の多くは、コードサンプルを示しています(たとえば、 registerLayout
やregisterPaint
)。 そのコードをどこに配置するのか疑問に思っている場合、答えはワークレットスクリプトにあります。
ワークレットはWebワーカーに似ており、スクリプトファイルをインポートして、(1)レンダリングパイプラインのさまざまなポイントで呼び出すことができ、(2)メインスレッドから独立しているJavaScriptコードを実行できます。
ワークレットスクリプトは、実行できる操作の種類を大幅に制限します。これは、高いパフォーマンスを確保するための鍵です。
複合スクロールとアニメーション
合成スクロールとアニメーションの公式仕様はまだありませんが、実際には、より有名で待望のHoudini機能の1つです。 最終的なAPIにより、開発者は、DOM要素のプロパティの限定されたサブセットの変更をサポートして、メインスレッドから離れたコンポジターワークレットでロジックを実行できるようになります。 このサブセットには、レンダリングエンジンにレイアウトやスタイルの再計算を強制せずに読み取りまたは設定できるプロパティ(変換、不透明度、スクロールオフセットなど)のみが含まれます。
これにより、開発者は、スティッキースクロールヘッダーや視差効果など、パフォーマンスの高いスクロールベースおよび入力ベースのアニメーションを作成できます。 これらのAPIがGitHubで解決しようとしているユースケースの詳細を読むことができます。
正式な仕様はまだありませんが、Chromeではすでに実験的な開発が始まっています。 実際、Chromeチームは現在、これらのAPIが最終的に公開するプリミティブを使用してCSSスナップポイントとスティッキーポジショニングを実装しています。 これは、Houdini APIが十分なパフォーマンスを発揮し、その上に新しいChrome機能が構築されていることを意味するため驚くべきことです。 Houdiniがネイティブほど速くないのではないかという恐れがまだある場合は、この事実だけで他の方法で納得できるはずです。
実際の例を確認するために、SurmaはChromeの内部ビルドで実行されているビデオデモを録画しました。 デモは、Twitterのネイティブモバイルアプリで見られるスクロールヘッダーの動作を模倣しています。 それがどのように機能するかを確認するには、ソースコードをチェックしてください。
あなたは今何ができますか?
前述のように、Webサイトを構築するすべての人はHoudiniを気にする必要があると思います。 将来的には、私たちの生活がずっと楽になるでしょう。 Houdini仕様を直接使用したことがない場合でも、ほぼ確実に、その上に構築されたものを使用します。
そして、この未来はすぐには起こらないかもしれませんが、おそらく私たちの多くが考えるよりも近いでしょう。 すべての主要なブラウザベンダーの代表者は、今年初めにシドニーで開催された最後のHoudini対面会議に出席し、何を構築するか、またはどのように進めるかについてほとんど意見の相違はありませんでした。
私が言えることから、それはHoudiniが物事になるかどうかの問題ではなく、いつ、そしてそれがあなた方全員の出番です。
ブラウザベンダーは、ソフトウェアを構築する他のすべての人と同様に、新機能を優先する必要があります。 そして、その優先順位は、多くの場合、ユーザーがこれらの機能をどれほどひどく望んでいるかによって決まります。
したがって、Webでのスタイリングとレイアウトの拡張性に関心があり、新しいCSS機能が標準プロセスを通過するのを待たずに使用できる世界に住みたい場合は、使用しているブラウザの開発者関係チームに、これが必要であることを伝えます。
もう1つの方法は、実際のユースケースを提供することです。これは、今日では困難または不可能なスタイリングとレイアウトで実行できるようにしたいことです。 GitHubのドラフトのいくつかにはユースケースのドキュメントがあり、プルリクエストを送信してアイデアを提供できます。 ドキュメントが存在しない場合は、ドキュメントを開始できます。
Houdiniタスクフォースのメンバー(および一般的にはW3C)は、Web開発者からの思慮深いインプットを本当に望んでいます。 スペック作成プロセスに参加するほとんどの人は、ブラウザーで作業するエンジニアです。 彼らは多くの場合、プロのWeb開発者ではありません。つまり、問題点がどこにあるかを常に把握しているわけではありません。
彼らは私たちに彼らに言うことを頼りにしています。
リソースとリンク
- CSS-TAG Houdiniエディタードラフト、W3CすべてのHoudiniドラフトの最新の公開バージョン
- CSS-TAG Houdiniタスクフォース仕様、GitHub仕様の更新と開発が行われる公式のGithubリポジトリ
- Houdiniサンプル、可能なAPIを紹介および実験するGitHubコードの例
- Houdiniメーリングリスト、W3C一般的な質問をする場所
この記事をレビューしてくれたHoudiniのメンバーであるIanKilpatrickとShaneStephensに特に感謝します。