原文
Philip Walton
2016年3月24日
CSS テクニック
CSS 機能を使用しようとしたものの、すべてのブラウザでサポートされているわけではないため使用できなかったことがありますか?さらに悪いことに、すべてのブラウザでサポートされていますが、このサポートにはバグが多く、パフォーマンスに一貫性がなく、あるいは完全な互換性さえありません。これらのことがあなたの身に起こったことがあるなら、そして私はきっと経験していると思いますが、Houdini に注意を払う必要があります。
Houdini は、これらの問題を永久になくすことに専念する新しい W3C ワーキング グループです。彼らは、一連の API を導入することで初めて CSS を拡張する機能を開発者に提供する予定であり、ブラウザのレンダリング エンジンのスタイルとレイアウト に 接続するためのツール セットを提供する予定です。
しかし、これは何を意味するのでしょうか?これは良い提案でしょうか?これは、私たち開発者が現在および将来の Web ページを構築するのにどのように役立つのでしょうか?
この記事では、これらの質問に答えていきます。しかし、答える前に、今日私たちが抱えている問題と、なぜそのような変化が必要なのかを理解することが重要です。次に、Houdini がこれらの問題をどのように解決するかをより詳細に説明し、今日の開発において非常にエキサイティングな機能をいくつか挙げます。最後に、Houdini を実現するために開発者が今できる具体的なことをいくつか紹介します。
私が記事を書いたり、新しい CSS 機能のデモを作成したりすると、必ず誰かがコメントやツイートをしてこう言います。 「素晴らしいですね!でも、おそらく今後 10 年は使用しないでしょう。」
このような迷惑で非建設的なコメントの気持ちは理解できます。歴史的には、機能提案が広く使用されるようになるまでには何年もかかりました。その理由は、Web の歴史を通じて、CSS に新しい機能を追加する唯一の方法は、標準プロセス全体を通過することであったからです。
標準的なプロセス手順 (大きな画像で見る)
もちろん、私は標準的なプロセスに反対するわけではありませんが、彼が時間をかけすぎていることは否定できません。
たとえば、フレックスボックスは 2009 年に初めて提案されましたが、開発者は今でも、ブラウザーのサポートがないために使用できないと不満を抱いています。もちろん、現在ではほとんどすべての最新のブラウザーが自動的に更新されるため、この問題は徐々に解決されていますが、最新のブラウザーであっても、機能の提案から一般提供までにはまだ遅れがあります。
興味深いことに、ウェブのすべての領域がこのようなわけではありません。最近 JavaScript で何が起こっているかを見てみましょう:
ポリフィル プロセスのステップ (大きな画像を参照)
この場合、必要なのはいくつかのアイデアは 1 日以内に製品化できます。つまり、実稼働環境ではすでに async / await を使用していますが、この機能はまだどのブラウザにも追加されていません。
2 つのコミュニティ間の一般的な感情の大きな違いもわかります。 JavaScript コミュニティでは、物事の変化が速すぎることについて不満を訴える人々に関する記事を読むことがあります。 CSS コミュニティでは、代わりに、いつ使えるようになるかわからないため、新しいことを学ぶことの無駄を嘆く人々の声が聞かれます。
最初に考えられるのは、CSS ポリフィルをさらに記述することが問題の解決策であると思われます。優れたポリフィルを使用すると、CSS は JavaScript と同じくらい速く前進できます。
残念ながら、事はそれほど単純ではありません。 CSS のポリフィルは非常に難しく、ほとんどの場合、パフォーマンスを完全に破壊することなく実行することはできません。
JavaScript は動的言語です。つまり、JavaScript を使用して JavaScript をポリフィルできます。また、動的であるため、拡張が特に簡単です。逆にCSSはCSSをポリフィルするのが難しいです。場合によっては、コンパイル手順中にコンパイル済み CSS を変換できます (PostCSS がこれを処理します)。ただし、DOM 構造または要素のレイアウト位置に基づいてプロパティをポリフィルしたい場合は、クライアント ロジックでポリフィルを実行する必要があります。
残念ながら、ブラウザ上でこのタスクを実行するのは簡単ではありません。
下の図は、ブラウザーが画面上に HTML ファイルを表示する方法の概要を示しています。青色でマークされた部分は、JavaScript が制御できる部分です。
JavaScript が制御できるレンダリング ワークフロー (拡大画像を表示)
に示された結果絵も同様に悲惨です。開発者は、ブラウザーが HTML と CSS を解析する方法や、HTML と CSS を DOM および CSS オブジェクト モデル (CSSOM) に変換する方法を制御できません。カスケードを制御することはできません。ブラウザが DOM 内で要素をどのようにレイアウトするか、画面上に要素を描画するかを制御することはできません。また、シンセサイザーを制御することもできません。
完全に制御できる唯一のプロセスは DOM です。 CSSOM は部分的にオープンですが、Houdini の Web サイトから引用すると、このオープン性は「未確認で、ブラウザー間で一貫性がなく、重要な機能が欠けています。」
たとえば、今日のブラウザーの CSSOM ではクロスが表示されません。 -domain スタイル シートを使用すると、認識できない CSS ルールや宣言を簡単に破棄します。つまり、ブラウザーがまだサポートしていない機能をポリフィルしたい場合は、CSSOM を使用できません。代わりに、DOM を調べて、タグやタグを見つけ、CSS スタイルを取得し、解析し、書き換えて、DOM に追加する必要があります。
もちろん、DOM を更新するということは、通常、ブラウザ全体がカスケード、レイアウト、描画、合成のすべての手順を再完了する必要があることを意味します。
JavaScript を利用してブラウザのレンダリング プロセスをポリフィルします。 (大きな画像を表示)
ページを完全に再描画することによるパフォーマンスへの影響は (特に一部の Web サイトでは) それほど大きくないように見えますが、これがどのくらいの頻度で発生するかを考えてください。ポリフィル ロジックがスクロール イベント、ウィンドウのサイズ変更、マウス操作、およびキーボード イベントに応答する必要がある場合 (基本的には随時変更するのと同じです)、状況は非常に明白であり、場合によっては非常に遅くなる場合もあります。
今日の CSS ポリフィルのほとんどに独自の CSS パーサーと独自のカスケード ロジックが含まれていることを認識すると、状況はさらに悪化します。また、解析とカスケードは非常に複雑な作業であるため、通常、これらのポリフィルは大きすぎるかバグがいっぱいです。
私が今述べたことを簡単に要約すると、ブラウザー (指定した CSS のせいで) がサポートしていないことをブラウザーに実行させたい場合は、DOM を更新および変更して自分で実行する必要があります。この効果を偽装します。残りのレンダリング手順では権限がありません。
これは私にとってこの記事全体の中で間違いなく最も重要な質問です。したがって、ざっと読んだ人は、このセクションをゆっくりと注意深く読む必要があります。
最後のセクションを読んだ後、「これは必要ない。内部をハッキングしたくないのは通常の Web ページを構築したいだけだ」と考えている人もいると思います。 ”
そう思うなら、一歩下がって、Web サイトの構築に使用されているテクノロジーについて慎重に検討することを強くお勧めします。年。ブラウザーのスタイル設定プロセスにアクセスしたり、それにフックしたりすることは、単なる派手なサンプルを構築することではありません。それは、開発者とフレームワーク作成者に次の 2 つの重要なことを実行する権限を与えることです。
ブラウザー間の違いを正規化する
人々が使用できるように、いくつかの新しい機能を発明してポリフィルします。
jQuery などの JavaScript ライブラリを使用したことがある場合は、この機能から大きな恩恵を受けるでしょう。実際、これは今日のほぼすべてのフロントエンド ライブラリまたはフレームワークの主なセールス ポイントです。 Github で最も人気のある 5 つの JavaScript ライブラリと DOM ライブラリ (AngularJS、D3、jQuery、React、Ember) はすべて、ブラウザ間の違いを減らすために多くの機能を備えているため、それらについて考える必要はありません。これらはすべて 1 つの API のみを公開しており、この API は正常に動作します。
ここで、CSS とそのクロスブラウザーの問題を思い出してください。 Bootstrap や Foundation などの最も人気のある CSS フレームワークでさえ、クロスプラットフォーム互換性を目指して構築されていますが、クロスブラウザーのバグを排除するわけではなく、バグを引き起こす慣行を回避しているだけです。また、CSS のクロスブラウザーのバグは過去の問題だけではありません。フレックスボックスなどの新しいレイアウト モードが登場した現在でも、ブラウザ間の非互換性に関する多くの問題に直面しています。
結論として、任意の CSS プロパティを使用でき、それがどのブラウザでも有効になり同じように動作することがわかったら、開発作業がどれほど楽になるか想像してみてください。次に、CSS グリッド、CSS スナップ ポイント、固定配置など、他のブログ投稿やカンファレンスで学んだ新機能を想像してください。これらを今すぐ使用できれば、ネイティブ CSS 機能と同じように動作するでしょう。必要なのは、Github からコードを取得することだけです。
これは Houdini の夢です。これが彼らが望む未来です。
つまり、CSS ポリフィルを作成したり、実験的な機能を開発したりする予定がない場合でも、他の人がそうできるようにしたいと思うかもしれません。これらのポリフィルが存在すると、誰もがその恩恵を受けることができるからです。有益です。
開発者はブラウザのレンダリング プロセスをほとんど制御できないと上で述べました。実際、制御できるのは DOM と CSSOM の一部だけです。
この問題を解決するために、Houdini ワーキング グループはいくつかの新しい仕様を導入しました。これにより、開発者はレンダリング プロセスの他の部分に初めてアクセスできるようになります。次の表は、新しい仕様でレンダリング プロセスのどの部分を変更できるかを示しています。 (灰色の仕様は計画されていますが、まだ書かれていないことに注意してください。)
ブラウザーのレンダリング プロセスに統合される新しい仕様の部分。 (大きな画像を表示)
以下のセクションでは、それぞれの新しい仕様を簡単に説明し、それらが提供するものについて説明します。この記事では触れていない別の仕様があることに注意してください。Houdini のドラフトの GitHub リポジトリから完全なリストを参照できます。
CSS パーサー API はまだ作成されていないため、ここで述べたことのほとんどは簡単に変更できます。しかし、基本的な考え方は、開発者が CSS パーサーを拡張し、新しいメディア ルール、新しい疑似クラス、ネスト、@extends、@apply などの新しい構成を開発者に通知できるようにすることです。
パーサーはこれらの新しい構造を認識すると、それらを破棄するのではなく、CSSOM 内の正しい場所に配置できます。
CSS にはすでにカスタム プロパティがあり、前に述べたように、それらのロックが解除される可能性に非常に興奮しています。 CSS プロパティと値 API はカスタム プロパティをさらに一歩進め、タイプを追加することでプロパティをさらに便利にします。
カスタム プロパティにタイプを追加すると多くの利点がもたらされますが、おそらく最大のセールス ポイントは、開発者がこれらのタイプにより、現在は使用できないトランジションやアニメーションをカスタム プロパティに追加できることです。
次の例を見てください:
body { --primary-theme-color: tomato; transition: --primary-theme-color 1s ease-in-out;}body.night-theme { --primary-theme-color: darkred;}
上記のコードでは、夜のテーマ カテゴリが ` 要素に追加されている場合、ページ上のすべての要素に --primary が設定されます。 -theme-color 属性 要素の値は、トマトからダークレッドにゆっくりと変化します。これを今すぐ実行したい場合は、カスタム プロパティを遷移できないため、各要素の遷移を手動で記述する必要があります。
この API のもう 1 つの非常に有望な機能は、「適用フック」を登録する機能です。これにより、開発者はカスケード ステップの完了後もカスタム プロパティの値を変更できます。これは非常に便利です。ポリフィルの機能。
CSS Typed OM は、現在使用されている CSSOM の 2 番目のバージョンと考えることができます。既存のモデルの多くの問題を解決することを目的としており、CSS パーサー API と CSS プロパティと値 API の新機能が導入されます。
Typed OM のもう 1 つの主な目標は、パフォーマンスを向上させることです。現在の CSSOM の文字列値を意味のある型付き JavaScript 式に変換すると、パフォーマンスが大幅に向上します。
CSS レイアウト API を使用すると、開発者は独自のモデルを作成できます。 「レイアウトモデル」では、基本的にすべてをCSSの表示プロパティに渡すことができます。これにより、開発者は初めて、ネイティブ レイアウト モデルの display:flex および display:table と同じくらい効率的にレイアウトできるようになります。
例として、Masonry レイアウト ライブラリは、CSS だけでは構築できないレイアウトを開発者がどのように実現しようとするかを示しています。これらのレイアウトは印象的ですが、残念ながら、特に性能の低いデバイスではパフォーマンスの問題が伴います。
CSS レイアウト API は、レイアウト名 (これは後で使用します) を受け入れる registerLayout メソッドと、すべてのレイアウト ロジックを導入する JavaScript クラスを開発者に提供します。以下は、 registerLayour を介してメーソンリーを定義する方法を示す基本的な例です。
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上記のレイアウト API と非常によく似ています。 registerLayout メソッドと同じように動作する registerPaint メソッドを提供します。開発者は、登録した名前を渡すだけで、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 要素は次のようになります。青い円を背景として表示します。円自体は中央に配置され、何が起こっても丸い要素自体のサイズは同じになります。
上記の仕様の多くはコード例を示しています (regstarLayout や registerPaint など)。このコードをどこに置くべきか疑問に思っている場合、その答えはワークレット スクリプトです。
ワークレットは、スクリプト ファイルをインポートして JavaScript コードを実行できるという点で Web ワーカーに非常に似ています。また、メインスレッドから独立して、レンダリングプロセス中のさまざまな場所で呼び出すことができます。
ワークレット スクリプトでは、高いパフォーマンスを確保するために使用できる操作の種類が大幅に制限されます。
合成スクロールとアニメーションの正式な仕様はまだありませんが、これは実際によく知られており、非常に話題になっている Houdini 機能の 1 つです。最終的な API では、開発者が複合ワークレットで論理操作を実行できるようになります。これはメイン スレッドから独立しており、指定された DOM 要素の属性の一部を変更できます。これらのプロパティは、再描画せずに変更できるプロパティのみになります。 (変換、不透明度、スクロール オフセットなど)。
これにより、開発者は効率的なスクロール アニメーションや、スティッキー スクロール タイトルや時差ボケ効果などの入力ベースのアニメーションを作成できるようになります。 Github にアクセスして、この API が何を解決しようとしているのかの例をさらに見ることができます。
公式ドキュメントはまだありませんが、Chrome 上で実験的な開発が開始されています。実際、Chrome チームは、CSS スナップ ポイントと固定位置を追加するために、この API が最終的に公開するメソッドを使用しています。これは、Houdini の API が十分に効率的であり、Chrome の新しい機能がその上に構築されていることを意味するため、非常に驚くべきことです。 Houdini がネイティブほど速くないのではないかとまだ心配している場合は、この事実に納得していただけるでしょう。
Surma は、Chrome で実行されているビデオ サンプルを録画しました。このデモは、Twitter のネイティブ モバイル アプリのスクロールする見出しを模倣しています。ソース コードをクリックすると、その動作を確認できます。
前に述べたように、Web サイトを構築するすべての人は Houdini に注目すべきだと思います。Houdini は将来私たちの生活を楽にしてくれるでしょう。 Houdini 仕様を直接使用したことがない場合でも、それに基づいたモジュールを必然的に使用することになります。
この未来はすぐにはやって来ませんが、多くの人が思っているよりも近いものになるでしょう。今年初めにシドニーで開催された最新の Houdini 対面カンファレンスには、すべての主要なブラウザ ベンダーが出席しました。何をすべきか、またこれらの問題をどのように組み立てるかについては、まだほとんど意見の相違がありません。
私が思うのは、問題は Houdini が実装されるかどうかではなく、いつ実装されるかということです。ここでもあなたが必要とされています。
ブラウザのメーカーは、ソフトウェア開発者と同様に、新機能を評価します。これらの優先順位は通常、ユーザーの希望によるものです。
Web 上のスタイルとレイアウトの拡張性が気になる場合は、将来、長い標準プロセスを待たずに新しい CSS 機能を使用できるようにしたい場合。次に、使用しているブラウザの開発者に相談して、この機能が欲しいことを伝えてください。
支援するもう 1 つの方法は、実際の使用例を提供することです。現在、スタイルとレイアウトを使用して達成するのは難しいであろう効果。 Github 上の一部のドラフトにはユースケースのドキュメントが含まれており、プル リクエストを送信してアイデアを提供できます。ドキュメントが存在しない場合は、作成できます。
Houdini ワーキング グループ (W3C など) は、Web 開発者からの提案を得ることに非常に興味を持っています。仕様の作成に関わっている人の多くはブラウザ開発エンジニアです。彼ら自身はプロの Web 開発者ではないため、問題点が何なのかまったくわかっていないことがよくあります。
私たちは彼らに伝える必要があります。
Houdini の最新のパブリック ドラフト バージョン。
仕様の更新と開発のための公式 Github リポジトリ。
可能な API を示し、実験するコード サンプル。
質問する場所。
この記事をレビューしてくれた Houdini メンバーの Ian Kilpatrick と Shane Stephens に感謝します
QR コードをスキャンして w3ctech WeChat 公式アカウントをフォローしてください