クラスを持つ最初の要素のCSSセレクター


947

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

.red:first-child {
    border: 5px solid red;
}
<p class="red"></p>
<div class="red"></div>

このセレクターの何が問題になっていますか、またどのように修正すればよいですか?

コメントのおかげで、要素が親の最初の子である必要があることがわかりましたが、これは私の場合とは異なります。私は次の構造を持っていて、コメントで述べられているようにこのルールは失敗します:

.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ですか?


私の例(p、div)の要素のタイプが異なるために混乱している人にとっては、それらを同じにすることも機能せず、問題はまだ存在しています。
Rajat

4
私は、これはどのように考えて:第一子のセレクタがすべき仕事をしている...
フェリックス・イヴ

28
:first-childは、それほど良い名前ではありません。息子がいて、次に娘がいたら、娘を長子とは呼べないでしょう。同様に、最初の.home> .redは.homeの最初の子ではないため、そのように呼び出すことは不適切です。
BoltClock

第一の型働いているはずです:いいえ、それはどのようだ
エヴァン・トンプソン

@EvanThompsonそのように:first-of-type 機能します。
TylerH

回答:


1426

これは、作者がどのように:first-child機能するかを誤解している著者の最も有名な例の1つです。CSS2導入され:first-child疑似クラスは、その親の最初の子を表します。それでおしまい。複合セレクターの残りの部分で指定された条件に最初に一致する子要素を選択するという非常に一般的な誤解があります。セレクターの動作方法(説明についてはこちらを参照)が原因で、それは単に正しくありません。

セレクターレベル3では、:first-of-type要素タイプの兄弟間の最初の要素を表す疑似クラスが導入されています。この回答は、との違いをイラストで説明:first-childしてい:first-of-typeます。ただし、と同様に:first-child、他の条件や属性は調べません。HTMLでは、要素タイプはタグ名で表されます。質問では、そのタイプはpです。

残念ながら、:first-of-class特定のクラスの最初の子要素を照合するための同様の疑似クラスはありません。Lea Verouと私が(完全に独立してではありますが)このために思いついた回避策の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"境界線を持ちます。

ルールの適用方法を次に示します。

<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. 最初のルールのみが適用されます。赤い枠が表示されます。
    この要素にはclassがredありますがred、親のクラスを持つ要素が前にありません。したがって、2番目の規則は適用されず、最初の規則のみが適用され、要素はその境界を維持します。

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

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

実際、兄弟コンビネーターがこの手法の唯一の重要なコンポーネントであり、そのような素晴らしいブラウザーサポートを備えているという事実により、この手法は非常に用途が広くなり、クラスセレクター以外の要素によるフィルタリングにも適用できます。

  • これを使用して:first-of-type、クラスセレクターの代わりにタイプセレクターを提供するだけで、IE7および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で使用する単一のセレクターで同じことを達成することはできませんまたはSeleniumのCSSロケーター。

Selectors 4 :nth-child()表記に拡張機能(元々はと呼ばれる完全に新しい疑似クラス:nth-match())を導入していることは言及に値します。これ:nth-child(1 of .red)により、架空ののようなものを使用できます.red:first-of-class。比較的最近の提案であるため、相互運用可能な実装がまだなく、本番サイトで使用することはできません。うまくいけば、これはすぐに変わるでしょう。それまでの間、私が提案した回避策はほとんどの場合に機能するはずです。

この回答は、質問が特定のクラスを持つすべての最初の子要素を探すことを前提としていることに注意してください。ドキュメント全体にわたる複雑なセレクターのn番目の一致には、疑似クラスも汎用のCSSソリューションもありません。ソリューションが存在するかどうかは、ドキュメントの構造に大きく依存します。jQueryが提供し:eq():first:lastおよびよりこの目的のために、しかし、それを再び注意して、彼らは非常に異なるから関数:nth-child()。Selectors 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))。各要素はその型の最初(かつ唯一)であり(pそしてdivそれぞれ)、セレクターによって両方が一致します。

特定のクラスの最初の要素がそのタイプの最初の要素でもある場合、疑似クラスは機能しますが、これは偶然にのみ発生します。この振る舞いはフィリップの答えに示されています。この要素の前に同じタイプの要素を挿入すると、セレクターは失敗します。更新されたマークアップを取る:

<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要素が2番目の p要素になるため、セレクターはすぐに失敗します。


15
それで、エミュレートする方法はあります:last-of-classか?クラスの最後の要素を選択します。
ロケットハズマット

1
@Rocket:わかりません:(
BoltClock

4
兄弟との素晴らしいテクニック。これは複数の兄弟コンビネーターで
Legolas

2
@BoltClockはい、申し訳ありませんが、私は解決策のためにここに来て、OP固有のケースについてはあまり気にしませんでした。特定のタイプに対してがのgeneral sibling selector ~ように機能する理由を実際には理解できません。:not(:first-of-*)一致する各要素にルールを適用する必要があると想定していますが、一致する可能性が3つ以上ある場合でも、最初の一致にのみ適用されます。
Gerard Reches、2016年

2
caniuseによると、:nth-child(1 of .foo)拡張機能はすでにSafari 9.1以降で実装されています。(私はまだチェックしていません)
Danield

330

:first-child名前が言うように、セレクタは、親タグの最初の子を選択するために、意図されます。子は同じ親タグに埋め込む必要があります。あなたの正確な例はうまくいきます(ここで試しただけです):

<body>
    <p class="red">first</p>
    <div class="red">second</div>
</body>

タグを別の親タグにネストしている可能性がありますか?クラスのタグはred本当に親の下の最初のタグですか?

これは、ドキュメント全体の最初のそのようなタグに適用されるだけでなく、新しい親が次のようにラップされるたびにも注意してください。

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

firstそして、third赤になります。

更新:

マーティンが彼の答えを削除した理由はわかりませんが、彼には解決策、:nth-of-typeセレクターがありました:

.red:nth-of-type(1)
{
    border:5px 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>

マーティンへのクレジット。ここに例のためのより多くの情報。これはCSS 3セレクタであるため、すべてのブラウザで認識されるわけではないことに注意してください(IE8以前など)。


それは私のせいかもしれません-私がMartynに指摘したよう:nth-of-typeに、CSS3セレクターは、現在のバージョンのIEでまったく機能しないというわずかな問題に悩まされています。
MARÖrlygsson

25
これを読んで少し混乱しました。厳密.red:nth-of-type(1)に、(a)その要素タイプの最初の子であり、(b)クラス「red」を持つすべての要素を選択します。したがって、例で、最初の<p>にクラス「red」がなかった場合、それは選択されません。あるいは、<span>と最初の<p>の両方にクラス「red」があった場合、両方が選択されます。 jsfiddle.net/fvAxn
デビッド

7
@Dan Mundy:はと:first-of-type同等な:nth-of-type(1)ので、もちろん機能します。また、私の回答で述べたのと同じ理由で、同じように失敗する可能性もあります。
BoltClock

4
@David :nth-of-type「type」と表示されている場合、「element / tag」を意味します。したがって、クラスなどではなく、要素のみを考慮します。
gcampbell

2
@gcampbell:はい、それがまさにそれが意味することであり、それがこの答えに欠陥がある理由です。すべての言語に要素を定義する「タグ」の概念があるわけではないため、「タイプ」という単語が選択された理由は、セレクターとHTML / XMLを結び付けないためです。
BoltClock

74

正解は次のとおりです。

.red:first-child, :not(.red) + .red { border:5px solid red }

パートI:要素が最初に親になり、クラスが「赤」である場合、境界を取得します。
パートII:「.red」要素が最初に親ではなく、クラス「.red」のない要素の直後にある場合、その境界も尊重するに値します。

フィドルまたはそれは起こりませんでした。

フィリップ・ドーブマイヤーの答えは受け入れられましたが、正しくありません-添付のフィドルを参照してください。
BoltClockの答えは機能しますが、スタイルを不必要に定義して上書きします
(特に、別の方法で別のボーダーを継承する場合の問題をborder:noneに宣言したくない)。

編集:非赤に続いて「赤」が数回ある場合、各「最初の」赤が枠になります。これを防ぐには、BoltClockの回答を使用する必要があります。フィドルを見る


2
この答えは間違っていません。セレクタ指定されたマークアップに対して正しいですが、編集で言及されている状況が、少なくともマークアップ構造を保証できない場合にオーバーライドが必要であると私が述べた理由であることを繰り返します。.redは、:not(.red)常に.red兄弟の中で最初になるわけではありません。境界線を継承する必要がある場合は、オーバーライドルールではborder: inheritなく宣言するだけborder: noneです。
BoltClock

3
このソリューションは、最後の子にも同じことを簡単に実行できるため、最高のIMOです。
A1rPun 2014年

@ A1rPun最後の子のためにこれをどのように変更しますか?
ウィレム

@Willemをに変更first-childするだけですがlast-child、テストの結果、これで常にうまくいくとは限らないことがわかりました。
A1rPun 2014

3
申し訳ありませんが、「クラス.redを持つ最初の子要素」とは一致せず、「クラス.redがあり、非.red要素の後に最初の.red要素がある場合、最初の要素」と一致します。これら2つは同等ではありません。フィドル:jsfiddle.net/Vq8PB/166
Gunchars、

19

あなたは使うことができますfirst-of-typenth-of-type(1)

.red {
  color: green;  
}

/* .red:nth-of-type(1) */
.red:first-of-type {
  color: 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>


6
クラスと最初の要素の<p></p>間にがある場合は機能しません。このJSFiddleを見てください。spanpred
フランシスコロメロ

1
彼の回答の最後の例では、私がここで指摘したのと同じ動作を再現していることがわかりました。私があなたの例を試して少し遊んだとき、私はその振る舞いに気づき、私は将来の読者が気付くように指摘したいと思いました。
フランシスコロメロ

13

上記の回答は複雑すぎます。

.class:first-of-type { }

これにより、クラスの最初のタイプが選択されます。MDNソース


4
first-typeへの参照は見つかりません。first-of-typeはタグ名にのみ適用されます。この答えは正しいですか?
Matt Broatch、


7
クラスでは機能しません。それはそれは方法ですすべきクラスのn番目を選択すると、タグのn番目を選択するよりも便利になるので、動作します。ただし、「:first-of-type」はtagNameでのみ機能します。'first-of-class'と 'first-of-tag'が同じ要素を参照することがよくあるので、それらがしばしばそうである場合、それがそのように機能していると考えて混乱するのは簡単です。そして、あなたが彼らがそうでないケースに来るとき、何が壊れているのかと思っています。
エヴァントンプソン

2
これが選択された答えではない理由がわかりません。これは、OPが要求していたことを正確に実行し、完全に機能します。SMH。
Bernesto

1
@Bernesto、同じ「タイプ」の要素が複数ある場合は<span>、と言ってhighlightください。いくつかはクラスを持っています。.highlight:first-of-typeセレクタは、この例では、まず、選択されたクラスと「タイプ」の最初のインスタンスを選択する<span>クラスの最初のインスタンスとしませんhighlight。spanの最初のインスタンスにもクラスの強調表示がある場合のみ、スタイルが実装されます。(codepen.io/andrewRmillar/pen/poJKJdJ
Sl4rtib4rtf4st

9

セレクタと一致するには、要素のクラス名がredであり、その親の最初の子である必要があります。

<div>
    <span class="red"> <!-- MATCH -->
</div>

<div>
    <span>Blah</span>
    <p class="red"> <!-- NO MATCH -->
</div>

<div>
    <span>Blah</span>
    <div><p class="red"></div> <!-- MATCH -->
</div>

これは正しいですが、これは私の問題のようですが、他の要素が先行しているかどうかに関係なく、クラスを持つ最初の要素を選択する方法はありますか?
Rajat

マーティンズの回答を見ていれば、これを尋ねる必要はありませんでした:)
フィリップ・ドーブマイヤー2010

9

他の回答はそれのどこが悪いをカバーしているので、私は残りの半分、それを修正する方法を試します。残念ながら、ここにCSSのみのソリューションがあることはわかりません。少なくとも、私が考えることはできません。ただし、他にもいくつかのオプションがあります。

  1. 次のfirstように、生成時に要素にクラスを割り当てます。

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

    CSS:

    .first.red {
      border:5px solid red;
    }

    このCSSは firstredクラスの両方を持つ要素にのみ一致します。

  2. または、JavaScriptで同じことを行います。たとえば、上記と同じCSSを使用して、これを行うために使用するjQueryは次のとおりです。

    $(".red:first").addClass("first");

少し前に CSSのみのソリューションを思いつきました。ここでは標準的な答えとしてそれを再現しました。
BoltClock

1
のようなものがない限り:first-of-class、最初の要素に追加のクラスを追加することもお勧めします。今のところ最も簡単な解決策のようです。
カイノアック2017

7

これは私のプロジェクトで入手しました。

div > .b ~ .b:not(:first-child) {
	background: none;
}
div > .b {
    background: red;
}
<div>
      <p class="a">The first paragraph.</p>
      <p class="a">The second paragraph.</p>
      <p class="b">The third paragraph.</p>
      <p class="b">The fourth paragraph.</p>
  </div>


5

更新された問題によると

<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>

いかがですか

.home span + .red{
      border:1px solid red;
    }

これにより、homeクラスが選択され、次にスパン要素、最後にスパン要素の直後に配置されるすべての.red要素が選択されます。

リファレンス:http : //www.w3schools.com/cssref/css_selectors.asp


3

nth-of-type(1)を使用することもできますが、サイトがIE7などをサポートする必要がないことを確認してください。これが当てはまる場合は、jQueryを使用して本体クラスを追加し、次にIE7本体クラスを介して要素を検索してから、要素名を追加します。それにn番目の子のスタイリングで。


3

コードをこのようなものに変更して機能させることができます

<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>

これはあなたのために仕事をします

.home span + .red{
      border:3px solid green;
    }

これはSnoopCodeからのCSSリファレンスです。


3

以下のCSSを使用して、リストul liの背景画像を作成しています

#footer .module:nth-of-type(1)>.menu>li:nth-of-type(1){
  background-position: center;
  background-image: url(http://monagentvoyagessuperprix.j3.voyagesendirect.com/images/stories/images_monagentvoyagessuperprix/layout/icon-home.png);
  background-repeat: no-repeat;
}
<footer id="footer">
  <div class="module">
    <ul class="menu ">
      <li class="level1 item308 active current"></li>
      <li> </li>
    </ul> 
  </div>
  <div class="module">
    <ul class="menu "><li></li>
      <li></li> 
    </ul>
  </div>
  <div class="module">
    <ul class="menu ">
      <li></li>
      <li></li>
    </ul>
  </div>
</footer>


2

これを試して :

    .class_name > *:first-child {
        border: 1px solid red;
    }

2

何らかの理由で、上記の回答のいずれも、親の本当の最初唯一の最初の子のケースに対処しているようには見えませんでした。

#element_id > .class_name:first-child

このコード内の最初のクラスの子だけにスタイルを適用する場合、上記のすべての回答は失敗します。

<aside id="element_id">
  Content
  <div class="class_name">First content that need to be styled</div>
  <div class="class_name">
    Second content that don't need to be styled
    <div>
      <div>
        <div class="class_name">deep content - no style</div>
        <div class="class_name">deep content - no style</div>
        <div>
          <div class="class_name">deep content - no style</div>
        </div>
      </div>
    </div>
  </div>
</aside>

1
あなたの答えは本質的にすでにこの質問の上位2つの最高の答えに含まれており、何も追加しません。また、:first-child疑似クラスの使用は誤解を招く可能性があります。.class_nameそれは、前に追加すると、動作方法が変更されず、単にフィルターとして機能するためです。以前にdivがある場合<div class="class_name">First content that need to be styled</div>、セレクターは実際の最初の子ではないため、一致しません。
j08691

私はそれが情報を必要とする人にとってはそれほど簡単ではないと思います。そして、はいあなたは事件について正しいです。これはより具体的なケースに役立ちます。だから便利かもしれないと思いました。
Yavor Ivanov 2016

これはまさに私が必要としていたもので、正確で簡潔です。ありがとう@YavorIvanov
quantme

1

これを試してみてください

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

-1

+直後に配置された要素を選択するために相対セレクターを使用すると、ここで最適に機能すると思います(以前はほとんど提案されていませんでした)。

このケースでこのセレクタを使用することも可能です

.home p:first-of-type

しかし、これはクラスセレクターではなく要素セレクターです。

ここにCSSセレクターの素晴らしいリストがありますhttps : //kolosek.com/css-selectors/


-2

この解決策を試してください:

 .home p:first-of-type {
  border:5px solid red;
  width:100%;
  display:block;
}
<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>

CodePenリンク


問題は、「クラスを持つ最初の要素のCSSセレクター」であり、「タグ名を持つ最初の要素のCSSセレクター」ではありません。
GeroldBroserがモニカを
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.