web-dev-qa-db-ja.com

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

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

.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を持つ最初の子をどのようにターゲットにできますか?

773
Rajat

これは、:first-childの仕組みを誤解している著者の最も有名な例の1つです。 CSS2で導入:first-child疑似クラスは親の最初の子を表します。それでおしまい。複合セレクタの残りの部分で指定された条件に最初に一致する子要素をピックアップするという非常に一般的な誤解があります。セレクターの動作方法により(説明については here を参照)、それは単に真実ではありません。

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

残念ながら、与えられたクラスの最初の子要素と一致する類似の:first-of-class擬似クラスはありません。 Lea Vero と私がこれを思いついた1つの回避策は、(完全に独立しているとはいえ)最初に、目的のスタイルをallそのクラスの要素に適用することです:

/* 
 * 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. 最初のルールのみが適用されます。赤い境界線がレンダリングされます。
    この要素にはクラスredがありますが、親にクラスredを持つ要素が先行することはありません。したがって、2番目のルールは適用されず、最初のルールのみが適用され、要素は境界を維持します。

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

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

実際、兄弟コンビネーターがこの手法の唯一の重要なコンポーネントであるという事実、、およびブラウザーの驚くべきサポートにより、この手法は非常に用途が広くなります。クラスセレクター以外の他の要素:

  • これを使用して、クラスセレクターの代わりにタイプセレクターを指定するだけで、IE7およびIE8の: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 */
    }
    
  • 属性セレクター 、またはクラスの代わりに他の単純なセレクターでフィルタリングできます。

  • 擬似要素は技術的には単純なセレクターではありませんが、このオーバーライド手法を pseudo-elements と組み合わせることもできます。

これが機能するためには、最初のルールをオーバーライドできるように、他の兄弟要素のデフォルトのスタイルを事前に知る必要があることに注意してください。さらに、これにはCSSのルールのオーバーライドが含まれるため、 Selectors 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() et alとは非常に異なる機能 であることに注意してください。 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

Philip Daubmeier によって受け入れられた元の回答の.red:nth-of-type(1)ソリューションは機能しますが(元は Martyn によって作成されましたが、その後削除されました)、動作はしません。それを期待しています。

たとえば、元のマークアップでpのみを選択したい場合:

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

... .red:first-of-type.red:nth-of-type(1)と同等)を使用することはできません。これは、各要素がそのタイプ(pおよびdivの最初の(そして唯一の)1つであるためですそれぞれ)、そのため、bothはセレクターと一致します。

特定のクラスの最初の要素もそのタイプの最初の要素である場合、擬似クラスは機能しますが、これは偶然によってのみ発生しますです。この動作は、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要素がsecondp要素であるため、セレクターはすぐに失敗します。

1317
BoltClock

:first-childセレクタは、その名前が示すように、親タグの最初の子を選択するためのものです。子は同じ親タグに埋め込む必要があります。あなたの正確な例はうまくいくでしょう(ちょうどそれを試してみました here ):

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

firstthirdは赤くなります。

更新:

私はなぜmartynが彼の答えを削除したのか知りませんが、彼は解決策、:nth-of-typeセレクタを持っていました:

<html>
<head>
<style type="text/css">
.red:nth-of-type(1)
{
    border:5px solid red;
} 
</style>
</head>

<body>
    <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>
</body>
</html>

Martyn へのクレジット。例えば here のようなより多くの情報。これはCSS 3セレクタなので、すべてのブラウザがそれを認識するわけではありません(例:IE 8以上)。

309

正しい答えは:

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

パートI:要素が最初にその親になり、クラス "red"を持つ場合、それはボーダーを取得します。
パートII:「.red」要素がその親の最初ではなく、クラス「.red」のない要素の直後に続く場合、それはまた、その境界の名誉に値するものとします。

Fiddleまたは発生しませんでした。

Philip Daubmeierの答えは、受け入れられてはいますが、正しくありません。添付のフィドルを参照してください。
BoltClockの答えはうまくいくでしょうが、不必要にスタイルを定義して上書きします
(特に別の方法で別の国境を継承するような問題 - あなたはborder:otherにotherを宣言したくないでしょう)

編集:あなたが赤ではないものに続いて「赤」を数回持っている場合は、それぞれの「最初の」赤が境界線を引きます。それを防ぐには、BoltClockの答えを使う必要があります。 フィドル を参照してください。

64
SamGoody

あなたはfirst-of-typeまたはnth-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>

14
Moes

セレクタと一致させるには、要素はクラス名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>
9
Chetan Sastry

他の答えは 間違った を含むものをカバーしているので、私は他の半分をどうやってそれを修正するかを試みます。残念ながら、ここに CSSのみ の解決策があるかどうかはわかりませんが、少なくとも は考えられません 。他にもいくつかの選択肢があります....

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

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

    CSS:

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

    このCSSは both firstクラスとredクラスを持つ要素にのみマッチします。 

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

    $(".red:first").addClass("first");
    
8
Nick Craver

更新された問題によると

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

これは class home を選択し、次に span を選択し、最後にspan要素の直後に配置される .red要素 を選択します。 

参照: http://www.w3schools.com/cssref/css_selectors.asp

5
StinkyCat

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

.class:first-of-type { }

これはファーストクラスのクラスを選択します。 MDNソース

4
Gabriel Fair

私はリストul liの背景画像を持つためにCSSの下で使っています

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

3
li bing zhao

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

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>

3
Yener Örer

Nth-of-type(1)を使うこともできますが、その場合はサイトがIE7などをサポートする必要がないことを確認してください。それにn番目の子スタイルで。

3
Jamie Paterson

うまくいくように、コードをこのようなものに変更することができます

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

これを試して :

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

これをシンプルで効果的に試す

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

何らかの理由で、上記の答えのどれも、 本当の最初の および だけの最初の子 の親の場合に対処しているようには見えなかった。

#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
Yavor Ivanov

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

 .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リンク

0
Santosh Khalse

最初に必要な段落だけを赤にします。どうやって?

<!DOCTYPE html><html><head><style>

article p:nth-child(1){background: red}
article p:first-child{background: red}

</style></head><body>

<p style="color:blue">Needed only first and only one paragraph had red. How?</p>

<article>
<p>The first paragraph.</p>
<div><p>The second paragraph.</p></div>
<p>The third paragraph.</p>
<div><p>The fourth paragraph.</p></div>
</article>

</body></html>