1. ホーム
  2. css

[解決済み] 最初の要素にクラスを指定するCSSセレクタ

2022-03-16 12:49:20

質問

クラス名 red を持つ最初の要素を選択できないようです。 class="red" を以下のCSSルールで使用します。

.home .red:first-child {
    border: 1px solid red;
}
<div class="home">
    <span>blah</span>
    <p class="red">first</p>
    <p class="red">second</p>
    <p class="red">third</p>
    <p class="red">fourth</p>
</div>

このセレクタのどこが問題で、どう修正すれば、クラス red ?

解決方法は?

これは、著者がどのように誤解しているかを示す最も有名な例の一つである。 :first-child は動作します。 CSS2 で導入された は、その :first-child 擬似クラスは の最初の子であり、その親である . これだけです。非常によくある誤解として、複合セレクタの残りの部分で指定された条件に最初にマッチした子要素をピックアップするというものがあります。セレクタの動作方法によって ( ここで の説明のとおり、それは真実ではありません。

セレクタレベル3では :first-of-type 擬似クラス は、その要素タイプの兄弟の中で最初の要素を表します。 この回答 との違いを図解入りで説明します。 :first-child:first-of-type . しかし :first-child は、他の条件や属性には目もくれません。HTMLでは、要素の種類はタグ名で表されます。この問題では、その型は p .

残念ながら、同様の :first-of-class 擬似クラスは、与えられたクラスの最初の子要素をマッチングするためのものです。この回答が最初に投稿された時点では セレクタのレベル4のFPWDが新たに発表された際に :nth-match() 擬似クラス 最初の段落で述べたように、セレクタリストの引数を追加することで、既存のセレクタの仕組みに沿って設計されており、この引数を通じて、複合セレクタの残りの部分を供給して、希望するフィルタリング動作を得ることができます。近年では、この機能は に吸収されました。 :nth-child() それ自体 という誤解を避けるために、セレクタリストはオプションの第2引数として表示されるようにしました。 :nth-match() は文書全体にマッチします(以下の最終的な注釈を参照)。

を待っている間に クロスブラウザ対応 (マジで10年近く経つが、そのうち5年間は1つの実装しかない)、1つの回避策として レア・ヴェロウ と私が独自に開発した(彼女が先にやった!)方法は、まず希望のスタイルを すべて そのクラスを持つ要素に

/* 
 * Select all .red children of .home, including the first one,
 * and give them a border.
 */
.home > .red {
    border: 1px solid red;
}

...そして、quot;undo" というクラスを持つ要素のスタイルは、quot;undo" となります。 の後に来る を使用します。 一般的な兄弟コンビネータ ~ をオーバーライドルールとして使用します。

/* 
 * Select all but the first .red child of .home,
 * and remove the border from the previous rule.
 */
.home > .red ~ .red {
    border: none;
}

これで、最初の要素だけが class="red" はボーダーを持つようになります。

このルールがどのように適用されるか、図解してみましょう。

.home > .red {
    border: 1px solid red;
}

.home > .red ~ .red {
    border: none;
}
<div class="home">
  <span>blah</span>         <!-- [1] -->
  <p class="red">first</p>  <!-- [2] -->
  <p class="red">second</p> <!-- [3] -->
  <p class="red">third</p>  <!-- [3] -->
  <p class="red">fourth</p> <!-- [3] -->
</div>

  1. 罫線は適用されず、枠線も描画されません。
    この要素はクラス red ということで、スキップされます。

  2. 最初の規則だけが適用され、赤いボーダーが描画されます。
    この要素には、クラス red しかし、その前にクラス red を親に持つ。したがって、2番目のルールは適用されず、1番目のルールだけが適用され、要素はボーダーを維持します。

  3. 両方のルールが適用され、ボーダーは描画されません。
    この要素は、クラス red . また、その前に少なくとも1つのクラスを持つ他の要素があります。 red . したがって、両方のルールが適用され、2番目の border という宣言は、最初の宣言を上書きし、いわば「元に戻す」ことになる。

おまけに、セレクタ3で導入されたものの、一般的な兄弟コンビネータは、IE7以降でかなりサポートされています。 :first-of-type そして :nth-of-type() で、IE9以降にしか対応していないものです。良いブラウザのサポートが必要な場合は、幸運です。

実は、この手法では兄弟コンビネーターが唯一の重要な構成要素であること。 このテクニックは非常に汎用性が高く、クラスセレクタ以外の要素によるフィルタリングにも適用できます。

  • を回避するために使用することができます。 :first-of-type の場合、クラスセレクタの代わりにタイプセレクタを指定するだけです(ここでも、質問における間違った使い方については、後のセクションで詳しく説明します)。

     article > p {
         /* Apply styles to article > p:first-of-type, which may or may not be :first-child */
     }
    
     article > p ~ p {
         /* Undo the above styles for every subsequent article > p */
     }
    
    
  • でフィルタリングすることができます。 属性セレクタ またはクラスの代わりに他の単純なセレクタを使用します。

  • また、このオーバーライドのテクニックを組み合わせることで 擬似要素 擬似要素は技術的には単純なセレクタではないのですが。

なお、これを実現するためには、他の兄弟要素のデフォルトのスタイルをあらかじめ知っておき、最初のルールを上書きできるようにしておく必要があります。さらに、これは CSS のルールを上書きすることになるため、同じことを セレクタAPI または セレン のCSSロケータを使用します。

最後に、この回答は、質問者が探しているのは 任意の数の は、与えられたクラスを持つ最初の子要素です。擬似クラスも、複雑なセレクタの n 番目のマッチに対する一般的な CSS ソリューションさえも存在しません。 ドキュメント全体の - が存在するかどうかは、文書構造に大きく依存します。 :eq() , :first , :last などがありますが、再度注意していただきたいのは、この目的のために とは全く異なる働きをします。 :nth-child() . セレクタAPIを使用することで、以下のように document.querySelector() を使えば、最初のマッチを得ることができます。

var first = document.querySelector('.home > .red');

または document.querySelectorAll() と、特定のマッチを選ぶためのインデクサーを持つ。

var redElements = document.querySelectorAll('.home > .red');
var first = redElements[0];
var second = redElements[1];
// etc


を使用していますが .red:nth-of-type(1) の解答は フィリップ・ダウブマイヤー が動作します(これは元々 マーティン が削除されたため)、期待するような動作はしません。

たとえば p をここで紹介します。

<p class="red"></p>
<div class="red"></div>

...すると .red:first-of-type (と同等)。 .red:nth-of-type(1) )、各要素はその型の最初の(そして唯一の)ものであるため、( pdiv というように、それぞれ ともに はセレクタにマッチします。

あるクラスの最初の要素が は、その型の最初のものでもあります。 の場合、擬似クラスは機能しますが これは偶然の産物である . この動作は、Philipの回答で実証されています。この要素の前に同じ型の要素をくっつけた瞬間に、セレクタは失敗します。質問からマークアップを取ります。

<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

でルールを適用する。 .red:first-of-type は動作しますが、一旦、別の p をクリックすると、クラスが表示されなくなります。

<div class="home">
  <span>blah</span>
  <p>dummy</p>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

...セレクタはすぐに失敗します、なぜなら最初の .red 要素が 第二 p 要素で構成されます。