0

Please explain why in some cases pseudo-classes in conjunction with CSS-selectors work and sometimes not.

The Code (https://jsfiddle.net/aspanoz/m1sg4496/):

 
div.wrapper {
  margin-bottom: 10px
}
div[class*="myclass"]:not(:first-of-type) {
  color: green
}
div[class*="myclass"]:first-of-type {
  color: red
}
<div class="wrapper">
  <div class="myclass">This text should appear red.</div>
  <div class="myclass">This text should appear green.</div>
  <div class="myclass">This text should appear green.</div>
  <div>this :first-of-type working as exepted</div>
</div>
<div class="wrapper">
  <div>but this :first-of-type fail</div>
  <div class="myclass">This text should appear red.</div>
  <div class="myclass">This text should appear green.</div>
  <div class="myclass">This text should appear green.</div>
</div>
Konstantin
  • 125
  • 1
  • 6
  • You might want to break this down into manageable pieces rather than dump a whole slew of examples all at once, – Paulie_D Jul 26 '16 at 15:21
  • Paulie_D, this look manageable? – Konstantin Jul 26 '16 at 15:25
  • as a side note: why are you using attribute selectors rather than the class selector (the dot)? i'm pretty sure attribute selectors used this way are more expensive. – Woodrow Barlow Jul 26 '16 at 15:27
  • I made this from a working example of the code, where the use of selektors needed. – Konstantin Jul 26 '16 at 15:39
  • This question has been asked about a hundred times. Please search harder for an answer. Also see the question I linked as a duplicate. –  Jul 26 '16 at 16:09

2 Answers2

0

The word "type" in the name of the :first-of-type pseudo-class refers to the tag type (i.e. tag name), not the selector that precedes it.

The official definition (from Selectors Level 3) is:

Same as :nth-of-type(1). The :first-of-type pseudo-class represents an element that is the first sibling of its type in the list of children of its parent element.

Here is the selector you've chosen.

div[class*="myclass"]:first-of-type

This code selects elements that meet both of the following conditions.

  1. The class attribute must contain "myclass", and
  2. It must be the first div element within its container.

In your second example, this selector results in fail-to-find because there are not elements which match both conditions.

There exists a bit of a CSS hack which can select only the first element that matches your selector. My code here is based on this very thorough answer. It depends on the general sibling selector and the nature of CSS specificity.

div.wrapper {
  margin-bottom: 10px
}

/* first select all of your items */
div[class*="myclass"] {
  /* apply the "special" styling here */
  color: red;
}

/* use general sibling selector to grab all except the first */
div[class*="myclass"] ~ div[class*="myclass"] {
  /* "undo" your style on these */
  color: green;
}
<div class="wrapper">
  <div>This text is unaffected.</div>
  <div class="myclass">This text should appear red.</div>
  <div class="myclass">This text should appear green.</div>
  <div class="myclass">This text should appear green.</div>
</div>

<div class="wrapper">
  <div class="myclass">This text should appear red.</div>
  <div class="myclass">This text should appear green.</div>
  <div class="myclass">This text should appear green.</div>
  <div>This text is unaffected.</div>
</div>

<div class="wrapper">
  <div class="myclass">This text should appear red.</div>
  <div class="myclass">This text should appear green.</div>
  <div>This text is unaffected.</div>
  <div class="myclass">This text should appear green.</div>
</div>
Community
  • 1
  • 1
Woodrow Barlow
  • 8,477
  • 3
  • 48
  • 86
  • Thank you. I thought that it works as a pipe in Linux shell – Konstantin Jul 26 '16 at 15:34
  • @Konstantin i just added an example that does what you were trying to do. – Woodrow Barlow Jul 26 '16 at 15:35
  • I agree, it works with my example. But it will not work if the classes will not go straight – Konstantin Jul 26 '16 at 15:50
  • @Konstantin they need to be at the same DOM level, but they don't need to be directly adjacent nodes. – Woodrow Barlow Jul 26 '16 at 15:53
  • wow! you helped me a lot, you have dispelled my misconceptions about the work of pseudo-classes and selectors ) and show the right way. thank you again. good luck – Konstantin Jul 26 '16 at 15:58
  • The Selectors 4 WD is severely out of date and should not be cited for the time being. In fact, 1) :nth-match() no longer exists in that form 2) but it lives on as an extension to :nth-child() 3) *and* it is supported by one major browser, Safari. Just that one for now, though, of course not nearly enough for it to be relevant yet. – BoltClock Jul 27 '16 at 03:25
  • Just saw that Rounin cited another answer of mine that discusses this. Here's the link again for anyone else seeing this: http://stackoverflow.com/questions/21167159/css-nth-match-doesnt-work/31415015#31415015 – BoltClock Jul 27 '16 at 03:27
-1

In the following:

div[class*="myclass"]:first-of-type {
  color: red
}

<div class="wrapper">
  <div>but this :first-of-type fail</div>
  <div class="myclass1">This text should appear red.</div>
  <div class="myclass1">This text should appear green.</div>
  <div class="myclass1">This text should appear green.</div>
</div>

You are telling the browser to find a div which:

i) is the first div; and

ii) has a class beginning with myclass.

The first div is the one without .myclass1 - therefore, it isn't coloured red.

The first appearance of .myclass1 is in the second div - to select that div correctly, you'd need to use:

div[class*="myclass"]:nth-of-type(2)

Why doesn't :first-of-type work?

type only refers to the type of element.

What you are looking for is a :first-of-query.

As yet, :first-of-query does not exist.

Rounin
  • 27,134
  • 9
  • 83
  • 108
  • 1
    what is `first-of-query`? is there a proposal for such a pseudo-class? – Woodrow Barlow Jul 26 '16 at 15:37
  • There's a proposal in my head for such a pseudo-class. – Rounin Jul 26 '16 at 16:18
  • Hmm. I have no idea why the answer above has received a negative vote. – Rounin Jul 26 '16 at 16:21
  • 1
    it wasn't me, if that's what you're implying. anyway, thought you might like to know that there is an official proposal called [`nth-of-match()`](https://www.w3.org/TR/selectors4/#selected-child-index). – Woodrow Barlow Jul 26 '16 at 17:27
  • No, I didn't think it was you, no worries. It just piqued my curiosity and I was thinking aloud. Thanks for the heads up on `:nth-match()` that caught my attention(!) - though, I understand from the answer by @BoltClock (here: http://stackoverflow.com/questions/21167159/css-nth-match-doesnt-work) that `:nth-match()` no longer exists. Speaking personally, I - and I'm sure many others - would _love_ to see an `:nth-of-query()` pseudo-selector. – Rounin Jul 26 '16 at 18:13