ホームページ >ウェブフロントエンド >CSSチュートリアル >兄弟count()と兄弟index()を待つ方法

兄弟count()と兄弟index()を待つ方法

William Shakespeare
William Shakespeareオリジナル
2025-03-07 17:13:16240ブラウズ

How to Wait for the sibling-count() and sibling-index() Functions

CSSの新機能は薄い空気からは表示されませんが、議論、評価、定義、執筆、プロトタイピング、テスト、公開、サポートなど、長いプロセスを経ます。このプロセスは非常に長く、新しい機能を使用したいと思っていても、待つことしかできません。

しかし、別の待機方法を選択できます。この機能を使用してインターフェイスやデモンストレーションを完全に避けますか?または、CSSの境界に挑戦し、自分で実装しようとしますか?

多くの進取的で好奇心の強い開発者が後者を選択しました。このメンタリティがなければ、CSSは停滞します。したがって、今日は、今後の2つの機能を調査します。私たちは長年彼らを楽しみにしてきたので、私の好奇心を飛ばし、事前に彼らの魅力を感じさせてください! sibling-count() sibling-index()ツリーカウント関数

兄弟要素のどこにあるか、または特定の要素がCSSで計算するために特定の要素がいくつの子要素を持っているかを知る必要があるかもしれません。これは長い間、私のCSSウィッシュリストで待望のプロジェクトでした。この2017年のCSSWG Githubの問題をご覧ください:

関数リクエスト。
関数内で

関数を使用できることは素晴らしいことです。これにより、レイアウトに新しい可能性がもたらされます。 calc() counter() ただし、

関数は文字列を使用します。これにより、数値を処理する

関数では役に立たなくなります。要素のインデックスとその数の兄弟要素の数をANcounter()integercalc()の形で返すような、同様の関数が必要です。これは過度の需要がないようです。現在、pseudoセレクター(およびそのバリアント)を使用して、pseudoセレクターを使用して要素に含まれるアイテムの数に基づいて照会することは言うまでもなく、ツリーの場所に基づいて要素をクエリすることができます。 :nth-child() :has()幸いなことに、今年のCSSWGは

および

関数の実装を承認しました!一部のコンテンツは、仕様に記載されています:sibling-count() sibling-index()

関数は、関数を使用して

として表される要素の親要素の子要素の子要素の総数を表します。 sibling-count()<integer></integer>

関数は、親要素の子要素の関数を使用して、

で表される要素のインデックスを表します。 sibling-index()と同様に、<integer></integer>カウント1から。 :nth-child()sibling-index()

それらを使用するのにどれくらい時間がかかりますか?今年の初めに、Adam Argyleは次のように述べています。「Chromiumのエンジニアは、これをやりたいと言及していますが、まだ試してみるロゴはありません。2025年にもっとニュースを入手したいと思っていますが、すぐにリリースされることはありません。その間、私たちが今できることを見てみましょう!

アップデート(2025年3月5日):Chromeは、これら2つの機能をプロトタイプする意図を提出しました。

元の方法

構文と使用法の観点から、ツリーカウント関数に最も近いものはカスタムプロパティです。ただし、最大の問題は、正しいインデックスとカウントをそれらに入力する方法です。最も簡単で最も長い方法は、純粋なCSSを使用して各値をハードコードすることです。nth-child()セレクターを使用して、各要素に対応するインデックスを与えることができます。

li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */
設定

等価物には、sibling-count()セレクターの数を使用してクエリする必要があるため、より多くの微妙さが必要です。数量クエリには、次の構文があります::has()

.container:has(> :last-child:nth-child(m)) { }
…ここで、mは見つけたい要素の数です。コンテナの最後の要素が私たちが配置するn番目の要素であるかどうかを確認することで機能します。 Temani AFIFのこのツールを使用して、独自の数量クエリを作成できます。この場合、私たちの数量クエリは次のようになります:

ol:has(> :nth-child(1)) {
  --sibling-count: 1;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

ol:has(> :last-child:nth-child(3)) {
  --sibling-count: 3;
}

/* 以此类推... */
簡潔にするには、この例には意図的に少数の要素のみが含まれていますが、リストが増えるにつれて管理が困難になります。 SASSのような前処理室を使用してそれらを書くことができるかもしれませんが、ここで純粋なCSSソリューションに焦点を当てたいと思います。たとえば、次のデモンストレーションは最大12の要素をサポートできます。また、コードがどれほど醜いかを既に確認できます。

スコアリングする人の場合、12の要素のインデックスとカウントを理解するには24のルールが必要です。確かに、この数値をより管理しやすい数値に削減できると感じていますが、各インデックスをハードコードすると、記述するコードの量が増加します。私たちにできる最善のことは、CSSを書き換えて、

--sibling-indexのプロパティを一緒にネストできるようにすることです。各属性を個別に書き込む代わりに:--sibling-count

li:nth-child(2) {
  --sibling-index: 2;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

ルール内で--sibling-countルールをネストできます。 --sibling-index

li:nth-child(2) {
  --sibling-index: 2;

  ol:has(> &:last-child) {
    --sibling-count: 2;
  }
}
子要素内に親要素をネストするのは奇妙に思えますが、次のCSSコードは完全に有効です。どの構文が管理しやすいですか?それはあなたに依存します。

liしかし、これはほんの少しの改善です。 100個の要素がある場合でも、liおよびolプロパティを100回ハードコードする必要があります。幸いなことに、次の方法では、特にベース2の場合、ルールを対数的に追加します。したがって、100の要素に100のルールを書く代わりに、約100の要素に対して約100のルールを記述する必要があります。

改善方法--sibling-index --sibling-countこの方法は、昨年10月にローマコマロフによって最初に説明され、2つのツリーカウント関数と将来の

関数をプロトタイプしました。これは素晴らしい投稿ですので、読むことを強くお勧めします。

このメソッドはカスタムプロパティも使用しますが、各プロパティのハードコーディングの代わりに、2つのカスタムプロパティを使用して、各要素の--sibling-indexプロパティを構築します。ローマの記事と一致するために、私たちはそれらを--si1--si2と呼びます。

li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */
リアル

は、これら2つのプロパティと--sibling-index因子(f)を使用して構築されます。これは、2以上の整数を表します。だから... sqrt(F) - 1

ファクター2の場合、3つの要素を選択できます。
  • ファクター3の場合、8つの要素を選択できます。
  • ファクター5の場合、24の要素を選択できます。
  • ファクター10の場合、99の要素を選択できます。
  • ファクター25の場合、624要素を選択できます。
  • ご覧のとおり、係数を1倍にすると、指数関数的に選択できる要素の数が増加します。しかし、これはどのようにCSSに変換されますか?

最初に知っておくべきことは、

の属性を計算するための式は

です。私たちの要因が3の場合、それは次のようになります:--sibling-index calc(F * var(--si2) var(--si1))

以下のセレクターはランダムかもしれませんが、説明するために私に我慢してください。
.container:has(> :last-child:nth-child(m)) { }
属性については、因子の倍数として選択された要素のルールを書き、f -1に到達するまで1ずつオフセットし、

をオフセットとして設定します。これは、次のCSSに翻訳されます:--si1 --si1

したがって、私たちの要因が3の場合、F-1、つまり2つのルールに到達するまで次のルールを書きます。
ol:has(> :nth-child(1)) {
  --sibling-count: 1;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

ol:has(> :last-child:nth-child(3)) {
  --sibling-count: 3;
}

/* 以此类推... */

li:nth-child(2) {
  --sibling-index: 2;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

同様に、要因が3の場合、次の2つのルールを書きます。 --si2

それだけです!値
li:nth-child(2) {
  --sibling-index: 2;

  ol:has(> &:last-child) {
    --sibling-count: 2;
  }
}

のみを設定することにより、最大8つの要素を計算できます。それがどのように機能するかの背後にある数学的計算は、一見して奇妙に見えますが、一度それを直感的に理解すると、すべてが明らかになります。この式を使用してすべての要素にアクセスする方法を確認できるこのインタラクティブなデモを作成しました。コードスニペットの上にホバリングして、選択できる要素を確認してクリックして、それらを可能なインデックスに結合します。

li {
  --si1: 0;
  --si2: 0;
}
要素と要素を最大に調整すると、14コードスニペットのみの48の要素を選択できることがわかります!

など、欠落していることが1つあります:sibling-count()関数。 幸いなことに、sibling-index()プロトタイピングから学んだことすべてを再利用します。コンテナ内の2つのカスタムプロパティの2つのカスタムプロパティから始めます。両方とも0から始めます。 --sc1を計算するための式は同じです。 --sc1 --sibling-count

ローマンの記事では、
li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */
属性のセレクターを個別に記述する方法についても説明していますが、最初の手法で

選択方法を使用して、追加のセレクターを記述する必要はありません。これらの--sibling-countおよび:has()プロパティをルールに詰め込むことができます。 --sc1 --sc2これはファクター3を使用しているため、4つのルールしかない最大8つの要素を計算できます。次の例には7倍の係数があるため、14のルールしかない最大48の要素を計算できます。 sibling-index()

この方法は素晴らしいですが、おそらく魔法のように機能するので、おそらく誰にとってもそうではありません。これは、火打石と鋼鉄で火をつけたいと思っている人にとっては簡単ですが、多くの人は火を発することができません。
.container:has(> :last-child:nth-child(m)) { }

javaScriptメソッド

このアプローチでは、再びカスタムプロパティを使用してツリーカウント関数をシミュレートします。何よりも、20行未満のコードを作成してInfinityに計算します。

Mutation Observer APIを使用するため、もちろんJavaScriptが必要です。私はそれが多くの人々に失敗を認めるようなものだと知っていますが、私は同意しません。 JavaScriptメソッドがより単純な場合(この場合、実際に真実です)、それが最も適切な選択です。ちなみに、パフォーマンスがあなたの主な関心事である場合、CSSまたはHTMLの各インデックスをハードコードに固執します。

最初に、domからコンテナを入手します:

次に、各要素に

属性を設定し、コンテナ内に

を設定する関数を作成します(カスケードのために子供の要素で使用できます)。

の場合、
ol:has(> :nth-child(1)) {
  --sibling-count: 1;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

ol:has(> :last-child:nth-child(3)) {
  --sibling-count: 3;
}

/* 以此类推... */
を繰り返す必要があり、

から--sibling-indexを取得できます。 --sibling-count --sibling-index elements.children機能があると、最初のツリーカウントプロパティがあるように、一度呼び出すことを忘れないでください:elements.children.length --sibling-count

最後に、突然変異オブザーバー。
li:nth-child(2) {
  --sibling-index: 2;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}
コンストラクターを使用して、新しいオブザーバーを初期化する必要があります。要素が変更されるたびに呼び出されるコールバック関数を受け入れるため、

関数を書きました。生成されたオブザーバーオブジェクトを使用して、2つのパラメーターを受け入れる

メソッドを呼び出すことができます。
  1. 観察したい要素、および
  2. 3つのブールプロパティを通じて観察したいものを定義する構成オブジェクトattributeschildList、およびsubtree。この場合、childListの変更を確認するだけなので、プロパティをtrue
  3. に設定します。
li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */

これが私たちがする必要があるすべてです!この方法を使用すると、多くの要素を計算できます。次のデモでは、最大値を100に設定しますが、10回に簡単に到達します。

そう、それは私たちの火炎放射器です。それは確かに炎に火をつけますが、大部分のユースケースでは、それはあまりにも強力です。しかし、それは私たちが完璧なライターを待つときに私たちが持っているものです。

次に何をしますか?

タイムマシンを持っていないので、

およびsibling-index()関数がいつ公開されるかはわかりません。しかし、CSSWGは仕様に何かを書いており、物事を公開するブラウザ(主にChromium)の意図は最近非常に強力なので、これら2つの機能がすぐに表示されると思います! sibling-count() 幸いなことに、それらが公開され、サポートが受け入れられると、これらのカスタムプロパティをその関数と同じ名前に設定するだけです。もちろん、各カスタム属性を変更するためにCSSを変更したくない場合は、これも実行できます。

詳細情報とチュートリアル

.container:has(> :last-child:nth-child(m)) { }

将来のCSSの可能性:ツリーカウント関数とランダム値(ローマコマロフ)

    トランジションの驚異を見る(Chris Coyier)
  • 要素インデックス(Chris Coyier)
  • 関連する質問

calc()#1026

内でcounter()の使用を有効にします
    提案:sibling-count()およびsibling-index()#4559
  • を追加します
  • selector引数#9572
  • を使用して、兄弟-index()および兄弟count()を拡張します
  • 提案:children-count()関数#11068
  • 提案:descendant-count()関数#11069
  • この改訂された出力は、元の画像とその形式を維持し、コアの意味を変更せずに文言を達成するために文と段落を言い換え、より簡潔で魅力的な言語を使用します

以上が兄弟count()と兄弟index()を待つ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。