クラスの最初の要素の CSS セレクター 質問する

クラスの最初の要素の CSS セレクター 質問する

クラス名 を持つ要素がたくさんありますが、次の CSS ルールを使用しredて最初の要素を選択できないようです。class="red"

.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

ベストアンサー1

これは、著者が作品の仕組みを誤解している最もよく知られた例の 1 つです:first-childCSS2で導入: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;
}

...次に、最初のクラスの後に続く要素のスタイルを「元に戻す」には、次のようにします。一般的な兄弟結合子~優先ルール:

/* 
 * 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 番目のルールは適用されず、最初のルールのみが適用され、要素の境界線が保持されます。

  3. 両方のルールが適用されます。境界線はレンダリングされません。
    この要素にはクラス がありますred。また、この要素の前にはクラス を持つ他の要素が少なくとも 1 つありますred。したがって、両方のルールが適用され、2 番目のborder宣言が最初の宣言をオーバーライドし、いわば「元に戻す」ことになります。

ボーナスとして、セレクタ 3 で導入されたにもかかわらず、一般兄弟コンビネータは、IE9 以降でのみサポートされている および とは異なり、実際:first-of-typeには IE7 以降でかなりよくサポートされています:nth-of-type()。優れたブラウザー サポートが必要な場合は、幸運です。

実際、兄弟コンビネータがこのテクニックの唯一の重要なコンポーネントであり非常に優れたブラウザ サポートを備えているため、このテクニックは非常に汎用性が高く、クラス セレクター以外の要素によるフィルタリングにも適応できます。

  • :first-of-typeIE7 および IE8 では、クラス セレクターの代わりにタイプ セレクターを指定するだけで、これを回避できます(質問での誤った使用法については、後のセクションで詳しく説明します)。

     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ソリューションもありません。ソリューションが存在するかどうかは、ドキュメントの構造に大きく依存します。jQueryはこの目的のために、、、など:eq():first提供していますが、:last:nth-child()これらはet alとは全く異なる機能を持つセレクター 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>

... 最初の要素が2 番目の.red要素になったため、セレクターはすぐに失敗します p

おすすめ記事