css3 селекторы и псевдоклассы

Пожалуйста, объясните, почему в некоторых случаях псевдоклассы в сочетании с CSS-селекторами работают, а иногда нет.

Код ( 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>

2 ответа

Решение

Слово "тип" в названии :first-of-type Псевдокласс относится к типу тега (то есть имени тега), а не к селектору, который ему предшествует.

Официальное определение (от уровня 3 селекторов):

Такой же как :nth-of-type(1), :first-of-type Псевдокласс представляет элемент, который является первым братом этого типа в списке дочерних элементов его родительского элемента.

Вот тот селектор, который вы выбрали.

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

Этот код выбирает элементы, которые удовлетворяют обоим из следующих условий.

  1. Атрибут class должен содержать "myclass", и
  2. Это должен быть первый элемент div внутри своего контейнера.

Во втором примере этот селектор приводит к невозможности найти, потому что нет элементов, соответствующих обоим условиям.

Существует немного хака CSS, который может выбрать только первый элемент, соответствующий вашему селектору. Мой код здесь основан на этом очень тщательном ответе. Это зависит от общего селектора братьев и сестер и характера специфики CSS.

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>

В следующих:

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>

Вы говорите браузеру, чтобы найти div который:

я) является первым div; а также

II) имеет класс, начинающийся с myclass,

Первый div без .myclass1 - следовательно, он не окрашен в красный цвет.

Первое появление .myclass1 находится во втором div - чтобы правильно выбрать этот div, вам нужно использовать:

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

Почему не :first-of-type Работа?

type относится только к типу элемента.

То, что вы ищете, это :first-of-query,

Пока что :first-of-query не существует.

Другие вопросы по тегам