Как мы все знаем, в спецификации CSS3 было добавлено множество селекторов псевдоклассов, которые заменяют большую часть работы JS, делая более удобным и эффективным изменение стиля путем получения узлов DOM.
Однако в процессе недавней разработки и использования я столкнулся со многими подводными камнями.Оказывается, нужно внимательно читать документацию, поэтому вот краткое изложение и разделение нескольких проблем, с которыми я столкнулся, и анализ нескольких пар селекторы через требование. Надеюсь, это будет полезно для всех.
нужно: Находит первый или последний элемент имени класса на странице.
:first-child / :last-child
Описано в руководстве по CSS3:
- :first-child: выбирает каждый дочерний элемент, который является первым дочерним элементом своего родительского элемента.
- :last-child: выбирает каждый дочерний элемент, который является последним дочерним элементом его родительского элемента
Это описание не может не заставить людей выглядеть немного затуманенными, так что давайте сразу перейдем к примеру:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
p:first-child {
border: 1px solid red;
}
p:last-child {
border: 1px solid blue;
}
</style>
</head>
<body>
<div>
<p>这是第一个段落。</p>
<p>这是第二个段落。</p>
<p>这是第三个段落。</p>
</div>
<div>
<p>这是第一个段落。</p>
<p>这是第二个段落。</p>
<p>这是第三个段落。</p>
</div>
</body>
</html>
результат:
Видно, что селекторы :first-child и :last-child будут выбирать первый или последний дочерний элемент указанного типа под родительским элементом из всех элементов на странице. Кажется, этот селектор несложно понять, так может ли этот селектор решить наши задачи? Позвольте мне увидеть следующий сценарий:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.p:first-child {
border: 1px solid red;
}
.p:last-child {
border: 1px solid blue;
}
</style>
</head>
<body>
<div>
<p class="p">这是第一个段落。</p>
<p class="p">这是第二个段落。</p>
<p class="p">这是第三个段落。</p>
</div>
<div>
<p>这是一个干扰段落。</p>
<p class="p">这是第一个段落。</p>
<p class="p">这是第二个段落。</p>
<p class="p">这是第三个段落。</p>
<p>这是一个干扰段落。</p>
</div>
</body>
</html>
результат:
В этом примере мы обнаружили, что вторая часть не достигла желаемого эффекта, почему так? Оказывается, селекторы :first-child и :last-child не так умны, как мы думали, все, что они могут сделать, это найти первый или последний элемент под родительским элементом, а когда мы хотим найти конкретный элемент через этот селектор. Первый и последний элемент класса будут выбраны тогда и только тогда, когда элемент удовлетворяет обоим условиям, поэтому резюмируем: Если вы хотите выбрать первый или последний элемент типа с помощью этого набора селекторов, вам необходимо выполнить- элемент принадлежит этому имени класса
- Элемент является первым или последним дочерним элементом под своим родительским элементом.
:first-of-type / :last-of-type
Чтобы лучше понять два вышеупомянутых селектора, давайте взглянем на эту пару.
Описано в руководстве по CSS3:
- : Первый из Тип: выбор каждого дочернего элемента родительского элемента, принадлежащего первым подэтам указанного типа
- : Last-of-type: выберите каждый дочерний элемент последнего указанного подэлемента типа, принадлежащего его родительскому элементу.
Давайте посмотрим пример:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
p:first-of-type {
border: 1px solid red;
}
p:last-of-type {
border: 1px solid blue;
}
</style>
</head>
<body>
<div>
<p>这是第一个段落。</p>
<p>这是第二个段落。</p>
<p>这是第三个段落。</p>
</div>
<div>
<p>这是第一个段落。</p>
<p>这是第二个段落。</p>
<p>这是第三个段落。</p>
</div>
</body>
</html>
результат:
На первый взгляд эта пара селекторов похожа на предыдущую пару, поэтому давайте рассмотрим следующий сценарий:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.p:first-of-type {
border: 1px solid red;
}
.p:last-of-type {
border: 1px solid blue;
}
</style>
</head>
<body>
<div>
<div>这是一个干扰段落。</div>
<p class="p">这是第一个段落。</p>
<p class="p">这是第二个段落。</p>
<p class="p">这是第三个段落。</p>
<div>这是一个干扰段落。</div>
</div>
<div>
<p>这是一个干扰段落。</p>
<p class="p">这是第一个段落。</p>
<p class="p">这是第二个段落。</p>
<p class="p">这是第三个段落。</p>
<p>这是一个干扰段落。</p>
</div>
</body>
</html>
результат:
В первой части мы обнаружили, что, когда родительский элемент содержит элементы других типов меток, мы все равно успешно выбрали указанный тип элемента, но когда тип метки других одноуровневых компонентов в родительском элементе совпадает с указанным нами элементом , у нас до сих пор нет возможности выделить первый и последний элемент, почему так? Это о том, как работают :first-of-type и :last-of-type- находит тип тега элемента указанного типа
- Найдите элемент под своим родителем, который соответствует
标签类型
Элементы - Тогда и только тогда, когда элемент соответствует типу, указанному в селекторе, и имеет тот же тип в родительском элементе.
标签
может быть выбран только тогда, когда первый или последний дочерний элемент в
:nth-child(n) / :nth-last-child(n)
Описано в руководстве по CSS3:
- :nth-child(n): выбирает n-й дочерний элемент, принадлежащий его родительскому элементу, независимо от типа элемента
- :nth-last-child(n): выбирает n-й последний дочерний элемент, принадлежащий его родительскому элементу, независимо от типа элемента
На самом деле, нетрудно увидеть из описания, что когда n равно 1, полученный результат будет таким же, как :first-child / :last-child, представленный в нашей первой группе, так что простая установка n в 1 решит нашу задачу. Проблема не в требованиях, поэтому вы должны спросить, зачем вводить эту пару селекторов.
На самом деле, с помощью двух вышеупомянутых наборов селекторов мы также обнаружили, что, когда наш сценарий приложения представляет собой контейнер с несколькими подэлементами одного и того же типа метки, очень сложно выбрать первый или последний элемент определенного имени класса. вещи, но если мы знаем, сколько элементов с одной и той же меткой до и после желаемого класса, мы можем использовать навязчивый подход, см. следующий пример.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.p:nth-child(2) {
border: 1px solid red;
}
.p:nth-last-child(2) {
border: 1px solid blue;
}
</style>
</head>
<body>
<div>
<p>这是一个干扰段落。</p>
<p class="p">这是第一个段落。</p>
<p class="p">这是第二个段落。</p>
<p class="p">这是第三个段落。</p>
<p>这是一个干扰段落。</p>
</div>
</body>
</html>
результат:
Таким образом, мы, наконец, достигли наших потребностей. Конечно, вы также можете использовать: nth-of-type (n) и: nth-last-of-type (n). После того, как у вас есть вышеуказанная основа, я верю, что каждый будет не понимаю Это сложно, поэтому я не буду вдаваться в подробности здесь.Суммировать
Напоследок подведем итоги: при решении этого требования мы фактически столкнулись с несколькими разными сценариями, для разных сценариев нужно использовать разные селекторы.
- Когда в родительском элементе есть только указанный тип: используйте :first-child / :last-child
- Когда есть другие элементы метки в дополнение к указанному типу под родительским элементом: используйте :first-of-type / :last-of-type
- В дополнение к указанному типу (имени класса) под родительским элементом есть другие подобные элементы метки, и количество других меток известно: используйте :nth-child(n) / :nth-last-child(n) или: n-й тип (n) / : n-й-последний-тип (n)
Из вышеизложенного мы также можем видеть, что возможен и другой сценарий, то есть когда под родительским элементом помимо указанного типа (определенного имени класса) есть другие аналогичные элементы метки, а количество других меток неизвестно, в этом сценарии я В настоящее время я не могу придумать хороший способ найти его с помощью CSS Каждый может добавить его.
Хотя это лишь малая часть CSS3, изучение знаний должно не только расширять, но и углублять и вдохновлять всех.