Селектор CSS для первого элемента с классом



у меня есть куча элементов с именем класса 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?

1875   18  

18 ответов:

это один из самых известных примеров непонимания авторами того, как :first-child строительство. введено в CSS2 на :first-child псевдо-класс представляет первый ребенок своего родителя. Вот и все. Существует очень распространенное заблуждение, что он выбирает тот дочерний элемент, который первым соответствует условиям, указанным остальной частью составного селектора. Благодаря тому, как работают селекторы (см. здесь для объяснения), то есть просто неправда.

селекторы Уровень 3 вводит :first-of-type псевдо-класс, который представляет собой первый элемент среди братьев и сестер его типа элемента. ответ объясняет, с иллюстрациями, разницу между :first-child и :first-of-type. Впрочем, как и с :first-child, он не смотрит на любые другие условия или атрибуты. В HTML, тип элемента представлен именем тега. В вопросе, что тип p.

к сожалению, нет ничего подобного :first-of-class псевдокласс для сопоставления первого дочернего элемента данного класса. Один обходной путь, что Леа Verou и я придумал для этого (хотя и совершенно независимо), чтобы сначала применить желаемые стили к все элементы с этим классом:

/* 
 * 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 в своего родителя. При этом второе правило не применяется, только первое, и элемент сохраняет свою границу.

  3. применяются оба правила; граница не отображается.
    Этот элемент имеет класс red. Ему также предшествует по крайней мере один другой элемент с классом red. При этом применяются оба правила, а второе 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 или селенлокаторы CSS.

стоит отметить, что селекторы 4 вводит расширение :nth-child() обозначение (изначально совершенно новый псевдо-класс :nth-match()), который позволит вам использовать что-то вроде :nth-child(1 of .red) вместо гипотетического .red:first-of-class. Будучи относительно недавним предложением, недостаточно совместимых реализации для его использования на производственных площадках пока нет. Надеюсь, это скоро изменится. В то же время, обходной путь, который я предложил, должен работать для большинства случаев.

имейте в виду, что этот ответ предполагает, что этот вопрос ищет каждый первый дочерний элемент с заданным классом. Нет ни псевдокласса, ни даже общего CSS-решения для n-го соответствия сложного селектора по всему документу - существует ли решение зависит сильно влияет на структуру документа. библиотека 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) решение в исходном принятом ответе Филипп Daubmeier работы (которая была первоначально написана Мартын но удалено с тех пор), он не ведет себя так, как вы ожидали бы.

например, если вы хотите выбрать 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 элемент сейчас второйp элемент.

The :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 селектор:

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

кредиты Мартын. Больше информации, например здесь. Имейте в виду, что это селектор CSS 3, поэтому не все браузеры распознают его (например, IE8 или более старый.)

правильный ответ:

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

Часть I: Если элемент является первым для своего родителя и имеет класс "красный", он должен получить границу.
Часть II: Если ".красный " элемент не является первым для своего родителя, но сразу же после элемента без класса ".красный", он также заслуживает чести указанной границы.

скрипка или этого не произошло.

Филипп Daubmeier, в то время как принято, не совсем корректно - см. прикрепленный скрипку.
BoltClock по ответ будет работать, но излишне определяет и перезаписывает стили
(особенно проблема, когда в противном случае она унаследует другую границу - вы не хотите объявлять другую границу:none)

изменить: В том случае, если у вас есть" красный "после не красного несколько раз, каждый" первый " красный получит границу. Чтобы предотвратить это, нужно было бы использовать ответ BoltClock. Смотрите скрипка

вы могли бы использовать 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>

чтобы соответствовать вашему селектору, элемент должен иметь имя класса 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>

так как другие ответы охватывают то, что неправильно С ним, я попробую другую половину, как это исправить. К сожалению, я не знаю, что у вас есть только CSS решение здесь, по крайней мере Не то, что я могу думать о. Однако есть и другие варианты....

  1. присвоить first класс для элемента при его создании, например:

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

    CSS:

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

    этот CSS только соответствует элементам с иfirst и red классы.

  2. в качестве альтернативы, сделайте то же самое в JavaScript, например вот что jQuery вы бы использовали для этого, используя тот же CSS, что и выше:

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

согласно вашей обновленной проблеме

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

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

Ссылка:http://www.w3schools.com/cssref/css_selectors.asp

вы можете изменить свой код на что-то вроде этого, чтобы заставить его работать

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

вот ссылка CSS от SnoopCode об этом.

Я использую ниже 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>

вы можете использовать nth-of-type(1), но убедитесь, что сайт не должен поддерживать IE7 и т. д., Если это так, используйте jQuery для добавления класса тела, затем найдите элемент через класс тела IE7, затем имя элемента, а затем добавьте к нему стиль nth-child.

попробуйте это :

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

Я получил это в моем проекте.

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>

приведенные выше ответы слишком сложны.

.class:first-of-type { }

Это позволит выбрать первый тип класса. источник MDN

по какой-то причине ни один из приведенных выше ответов, казалось, не касался случая настоящая первая и только первый ребенок родителя.

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

попробуйте это просто и эффективно

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

попробуйте это решение:

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

требуется только первый и только один абзац сделать красным. Как?

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

Я считаю, что с помощью относительного селектора + для выбора элементов, размещенных сразу после, работает здесь лучше всего (как несколько предложенных ранее).

в этом случае также можно использовать этот селектор

.home p:first-of-type

но это селектор элементов, а не класс один.

здесь у вас есть хороший список селекторов CSS:https://kolosek.com/css-selectors/

Comments

    Ничего не найдено.