некоторые хитрости работы с одноуровневыми элементами
От автора: если вы когда-либо использовали смежные селекторы CSS одного уровня, вы знаете, что их всего два. Комбинатор + выбирает первое соответствие, которое находит сразу после, а комбинатор ~ выбирает все последующие.
Но у нас нет способа выбрать те, которые расположены раньше. Либо родительские селекторы, либо предыдущие селекторные одного уровня — такого просто нет.
Я знаю, что вы этого хотите, вы знаете, что я этого хочу, но суровая правда в том, что они не существуют (и, вероятно, никогда не будут). Есть миллион сообщений «Почему?». Есть даже предложения о том, как их реализовать. Но мы застреваем на однонаправленной обработке правил CSS — это делается, скорее всего, чтобы защитить нас от «плохого опыта», связанного с неправильным течением потока обработки или даже бесконечными циклами.
К счастью, как и в случае большинства ограничений CSS, мы можем имитировать это. Первое, что нужно учитывать — это то, для чего нам нужны предыдущие одноуровневые элементы. Существуют два случая:
Нам нужно выбрать все элементы одного уровня с элементом, а комбинатор ~ выбирает только те, которые расположены после.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнееНам нужно выбрать только элементы одного уровня, которые расположены раньше
1. Выбор всех элементов одного уровня
Иногда нам нужно выбрать как предыдущие, так и последующие элементы одного уровня. Для этого мы можем выбрать родительский элемент и использовать некоторые хитрости.
Например, чтобы выбрать все span в следующей структуре, когда мы наводим указатель мыши на любой из них, мы могли бы просто использовать селектор дочерних элементов для родителя. Нам нужно переключить pointer-events с родителя на дочерние элементы. Таким образом, любое действие, которое мы хотим осуществить, будет срабатывать только при вводе для дочернего элемента, а не самого родителя.
<div> <span> 1st element </span> <span> 2nd element </span> <span> 3rd element </span> </div>
<div> <span> 1st element </span> <span> 2nd element </span> <span> 3rd element </span> </div> |
.container{ pointer-events:none } .container > span{ pointer-events: auto; } .container:hover > span{ background: red; /*или что угодно, что вы хотите сделать с со всеми элементами одного уровня, когда вы наводите мышь на один из них */ }
.container{ pointer-events:none } .container > span{ pointer-events: auto; } .container:hover > span{ background: red; /*или что угодно, что вы хотите сделать с со всеми элементами одного уровня, когда вы наводите мышь на один из них */ } |
Если вам нужно выбрать все элементы одного уровня, кроме того, на который был наведен курсор, вы можете совместить предыдущий метод с селектором :not, чтобы исключить его. Стандартным примером для этого является меню:
<ul> <li>first item</li> <li>second item</li> <li>third item</li> </ul>
<ul> <li>first item</li> <li>second item</li> <li>third item</li> </ul> |
ul:hover > li:not(:hover){ opacity: 0.5; }
ul:hover > li:not(:hover){ opacity: 0.5; } |
В приведенном выше коде будет переключаться непрозрачность всех элементов li, кроме того, что на который наведен курсор.
Кроме того, вы можете использовать селекторы type и nth, чтобы дополнительно отфильтровать нужные элементы. Задав определенные стили, мы можем получить следующее:
Обратите внимание: если вы хотите использовать подход pointer-events:none, помните, что это может нарушить порядок стекирования (возможно, вы выберете элементы, которые «ниже» в порядке стекирования). Это также не будет работать в IE10 и ниже, если только вам не нужны указатели события для чего-то другого. Поэтому будьте очень осторожны при использовании.
2. Выбор предыдущих элементов
Для этого варианта использования мы можем изменить в обратном направлении порядок сортировки в HTML, а затем отсортировать элементы обратно в CSS и использовать селекторы ~ и +. Таким образом, мы будем выбирать следующие элементы, но самом деле это будут предыдущие.
Существует несколько способов сделать это. Самый простой и, вероятно, самый старый — это изменение направления написания нашего контейнера:
<div> <span> 3rd element </span> <span> 2nd element </span> <span> 1st element </span> </div>
<div> <span> 3rd element </span> <span> 2nd element </span> <span> 1st element </span> </div> |
.container{ direction: rtl; /* встроенные элементы будут размещаться справа на лево */ }
.container{ direction: rtl; /* встроенные элементы будут размещаться справа на лево */ } |
Если ваши элементы должны отображать фактический текст, вы всегда можете отменить это обратно:
.container > span { direction: ltr; }
.container > span { direction: ltr; } |
Но во многих случаях это может быть неудобно. К счастью, современный инструментарий CSS позволяет сделать это намного проще и безопаснее. Мы можем просто использовать для контейнера Flexbox и изменить порядок с помощью flex-direction: row-reverse:
.container{ display:flex; flex-direction: row-reverse; }
.container{ display:flex; flex-direction: row-reverse; } |
Лучшее в этом подходе то, что мы не вносим путаницу в направление написания. Нам не нужно перезагружать дочерние элементы, и все гораздо более предсказуемо.
Использование «предыдущих элементов одного уровня» для создания системы звезд-рейтингов на чистом CSS
Семантически, рейтинговую систему можно рассматривать как простой список радио-кнопок с соответствующими метками. Это позволит нам использовать проверенный псевдо-селектор :checked для изменения элементов одного уровня. Итак, давайте начнем с этого:
<div> <input type=»radio» name=»rating» value=»5″><label for=»5″>☆</label> <input type=»radio» name=»rating» value=»4″><label for=»4″>☆</label> <input type=»radio» name=»rating» value=»3″><label for=»3″>☆</label> <input type=»radio» name=»rating» value=»2″><label for=»2″>☆</label> <input type=»radio» name=»rating» value=»1″><label for=»1″>☆</label> </div>
<div> <input type=»radio» name=»rating» value=»5″><label for=»5″>☆</label> <input type=»radio» name=»rating» value=»4″><label for=»4″>☆</label> <input type=»radio» name=»rating» value=»3″><label for=»3″>☆</label> <input type=»radio» name=»rating» value=»2″><label for=»2″>☆</label> <input type=»radio» name=»rating» value=»1″><label for=»1″>☆</label> </div> |
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнееКак мы рассматривали ранее, элементы находятся в обратном порядке тому, который позволяет нам применить селектор «предыдущий элемент одного уровня». Обратите внимание, что мы используем для представления пустых звезд символ юникода “white star” (U + 2606).
Давайте отобразим их рядом друг с другом, в правильном (обратном) порядке:
.rating { display: flex; flex-direction: row-reverse; }
.rating { display: flex; flex-direction: row-reverse; } |
Теперь скроем сами переключатели, никому не нужно их видеть:
.rating > input{ display:none; }
.rating > input{ display:none; } |
И применим некоторые стили к символам звездочек:
.rating > label { position: relative; width: 1.1em; font-size: 15vw; color: #FFD700; cursor: pointer; }
.rating > label { position: relative; width: 1.1em; font-size: 15vw; color: #FFD700; cursor: pointer; } |
Единственная действительно важная строка — это position: relative. Это позволит нам по абсолютно позиционировать псевдо-элемент с закрашенной звездой (U + 2605), который будет изначально скрыт.
.rating > label::before{ content: «\2605»; position: absolute; opacity: 0; }
.rating > label::before{ content: «\2605»; position: absolute; opacity: 0; } |
.rating > label:hover:before, .rating > label:hover ~ label:before { opacity: 1 !important; /* shame… shame… shame… I’ll explain that later*/ }
.rating > label:hover:before, .rating > label:hover ~ label:before { opacity: 1 !important; /* shame… shame… shame… I’ll explain that later*/ } |
То же делается для выбранного рейтинга, через сопоставление всех меток, которые находятся перед выбранной радио-кнопкой:
.rating > input:checked ~ label:before{ opacity: 1; }
.rating > input:checked ~ label:before{ opacity: 1; } |
Помните, что использование флага !important прямо противоположно хорошей практике. Я делаю это здесь, так как другого способа реализовать данный функционал нет.
И последнее, но не менее важное: нам нужно «запомнить» текущий рейтинг, на случай, если пользователь захочет его изменить. Например, если он выбрал пять звезд и по какой-либо причине хочет изменить их на четыре, мы должны отображать звезды с 1 по 4, как заполненные, а пятую — полупрозрачной при наведении указателя на четвертую.
Это может быть достигнуто путем изменения при наведении курсора на контейнер непрозрачности предыдущих элементов одного уровня выбранного ввода:
.rating:hover > input:checked ~ label:before{ opacity: 0.4; }
.rating:hover > input:checked ~ label:before{ opacity: 0.4; } |
Вот для чего нам нужно pacity:1 !important в начальном объявлении наведения. В противном случае это последнее правило переопределило бы другие в соответствии со специфичностью и применило полупрозрачную заливку ко всему.
И там у нас есть это, кроссбраузерная, полностью функциональная система звезд-рейтингов с использованием только селекторов «предыдущие элементы одного уровня».
Как вы можете видеть, просто потому, что «это невозможно» не означает, что вы не должны пытаться. Программирование — это раздвижение границ. Поэтому каждый раз, когда вы упираетесь в стену, просто попробуйте надавить немного сильнее. Или лучшей аналогией, я думаю, будет — найдите свой обходной путь? … в любом случае, вы понимаете, что я имею в виду. Продолжайте взламывать!
Замечания относительно доступности
Предыдущий фрагмент — это упрощение для лучшего понимания. Это не то, что я бы рекомендовал использовать в реальной среде из-за многих ограничений доступности.
Чтобы сделать сниппет немного более доступным, первым делом нужно было бы скрыть радио-кнопки с помощью другого способа, а не display: none, чтобы сделать их фокусируемыми. Мы также должны добавить кольцо фокусировки на весь фрагмент звёзд, когда любой элемент внутри выделен фокусом, это делается через псевдо-селектор :focus-in.
Метки «звезды» не имеют смысла для экранных дикторов, поэтому наилучшим подходом будет наличие внутри метки span с текстом «n Stars», который будет скрыт от видящих пользователей.
Кроме того, подход с обратным порядком в HTML-источнике + display:row-reverse делает клавиатуру неудобной для выставления рейтингов. Доступность Flexbox и клавиатуры — довольно сложная тема, но ближе всего к решению подход, когда для каждого элемента добавляется тег aria-flowtotag, что, по крайней мере, устраняет проблему для некоторых экранных дикторов + комбинации браузеров.
Более доступный сниппет (использующий альтернативную технику изменения следующих элементов одного уровня, которые выглядят пустыми) вы можете найти у Патрика Коула, как описано в комментариях ниже.
Автор: Facundo Corradini
Источник: https://medium.freecodecamp.org/
Редакция: Команда webformyself.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнееPSD to HTML
Практика верстки сайта на CSS Grid с нуля
СмотретьПродвинутые CSS-селекторы, о которых вы не знали
В каскадных таблицах стилей элементам страницы присваиваются значения атрибутов id и CSS class для того, чтобы стилизовать их. Но что делать, если у вас нет доступа к коду, чтобы добавить эти? К счастью существуют динамические селекторы, которые являются единственным решением в этой ситуации.
Дальше я собираюсь рассказать о работе селекторов атрибутов, но рекомендую с самого начала применять идентификаторы и классы, так как использование селекторов не всегда полезно. В процессе поиска элемента (CSS или JavaScript) браузеру приходиться «обойти» весь DOM страницы, чтобы найти нужный.
При использовании селекторов атрибутов на поиск затрачивается больше ресурсов и времени. Поэтому не стоит злоупотреблять селекторами и применять вместо них CSS id или class. Их нужно использовать только в том случае, если нет другого выхода. Например, когда HTML-код генерируется динамически, и вы никак не можете добавить в него классы или идентификаторы.
($=) – атрибут оканчивается определенным значением
Выбор элемента с помощью CSS, значение которого заканчивается определенным символом (суффиксом) выглядит следующим образом:
div[id$=“_myDiv”] { // CSS правило }
Атрибут id$ находится внутри скобок элемента div. Обратите внимание, что вместо тега div можно указать любой другой HTML-элемент от input до span и так далее. Этот пример идеально подойдет для выбора элемента, если суффикс внутри атрибутов формируется динамически.
Пример:
<!-- HTML --> <div> Какой-то текст </div>
Чтобы выбрать этот элемент div, нужно использовать следующий селектор:
div[id$="_LoginPanel"] { margin: 0 3em; padding: 1em; }
Нам необходимо указать $ после id атрибута в скобках. Затем в кавычках добавить суффикс элемента, на который нацелились:
div[id$=“myDynamicDiv”] { // CSS правила }
Этот селектор можно использовать для любых элементов (div, span, img и т.д.), а также любых их атрибутов (id, name, value и class HTML CSS).
(^=) — атрибут начинается с определенного значения
Можно выбирать элементы, значение атрибутов которых начинается с определенного префикса. Делается это по аналогии с описанным выше селектором ($=):
<!-- HTML --> <div> <h2>My custom panel</h2> </div>
Селектор будет выглядеть следующим образом:
div[class^="myPanel_"] { // CSS правила }
Единственное отличие двух описанных CSS class selector состоит в том, что перед знаком = (равно) указываются разные символы. В этом примере использован атрибут class, вместо id.
(* =) — атрибут содержит некоторое значение
Что делать, если и префикс и суффикс атрибутов генерируется динамически? В данном случае нужно найти элемент, значение атрибута которого содержит параметр:
<div> <h2>Какой-то текст</h2> <form>...</form> </div>
Выбор этого элемента будет выглядеть следующим образом:
div[class*="logoutPanel"] { // CSS правила }
Таким образом, любой div, который содержит название класса “logoutPanel” будет выбран и к нему будут применены определенные стили.
(=) – атрибут со значением
Это еще один способ выбора элемента с определенным значением id, CSS class, name, value и т.д.:
<!-- HTML --> <div class=“3453_mydynamicdiv”> <h2>My Dynamic Div</h2> </div>
Можно обратиться к элементу div, используя указанный выше атрибут = или через атрибут класса:
// 1-й способ – выбор конкретного элемента класса div[class="3453_mydynamicdiv"] { // CSS правила } // 2-й способ – выбор всех элементов класса .3453_mydynamicdiv { // CSS правила }
Краткий обзор селекторов атрибутов:
- = значение атрибута эквивалентно определённым символам;
- $= значение атрибута оканчивается определенными символами;
- ^= значение атрибута начинается с определенных символов;
- *= значение атрибута содержит определенные символы.
Перед тем, как задать параметры class в CSS, нужно понимать, что псевдоклассы селекторов – это CSS селекторы с двоеточием перед ними. Многие из них часто используются для ссылок или интерактивных элементов:
a:hover {} a:active {} a:focus {} a:visited {} :checked {} :first-child {} :last-child {} // вы поняли
Это удобно, когда необходимо получить доступ к каким-либо элементам, находящимся в определенном состоянии.
Селектор псевдокласса :not(x) удаляет из набора определенные элементы на основе переданного параметра. Это полезно при стилизации всех элементов:
<ul> <li>Blog</li> <li>About</li> <li>Videos</li> <li>Music</li> <li>Merch</li> </ul>
С его помощью можно выбрать все элементы за исключением элемента с классом highlight, как в этом примере:
.nav li:not(.highlight) { margin: 0 1em 0 0; padding: 5px 16px; display: inline-block; }
Можно пойти дальше и выбирать любые атрибуты.
Например:
В CSS кроме псевдоклассов существуют и псевдоэлементы. К ним как раз относится псевдоэлемент ::first-letter. С его помощью можно стилизовать первую букву любого абзаца. Этот эффект часто применяется в печатных изданиях. Создать заглавную букву при помощи псевдоэлемента ::first-letter довольно просто:
p::first-letter { // стиль буквы }
Если не хотите стилизовать первые буквы в каждом абзаце, можно выбрать только первый абзац во всем тексте. Для этого нужно использовать вместе псевдокласс и псевдоэлемент (:first-child и ::first-letter):
p:first-child::first-letter { // добавляем стили только к первой букве первого абзаца текста }
Этот подход освобождает от необходимости использования JavaScript.
Этот псевдокласс я использую довольно часто. Он позволяет выбрать первый элемент определенного типа внутри родительского и применить к нему CSS class:
article:first-of-type { margin-top: 0; }
:first-of-type не бывает без :last-of-type. Как вы уже наверное догадались, этот селектор работает противоположно селектору :first-of-type:
article:last-of-type { border-bottom: none; margin-bottom: 0; }
Вы познакомились с «продвинутыми» CSS class selector, о которых не слышали раньше или никогда не сталкивались с ними. В любом случае я рекомендую вам ознакомиться с ними поближе и, возможно, вы будете чаще использовать их для решения своих повседневных задач по верстке.
Данная публикация представляет собой перевод статьи «Advanced CSS Selectors you never knew about» , подготовленной дружной командой проекта Интернет-технологии.ру
Соседние селекторы | htmlbook.ru
Соседними называются элементы веб-страницы, когда они следуют непосредственно друг за другом в коде документа. Рассмотрим несколько примеров отношения элементов.
<p>Lorem ipsum <b>dolor</b> sit amet.</p>
В этом примере тег <b> является дочерним по отношению к тегу <p>, поскольку он находится внутри этого контейнера. Соответственно <p> выступает в качестве родителя <b>.
<p>Lorem ipsum <b>dolor</b> <var>sit</var> amet.</p>
Здесь теги <var> и <b> никак не перекрываются и представляют собой соседние элементы. То, что они расположены внутри контейнера <p>, никак не влияет на их отношение.
<p>Lorem <b>ipsum </b> dolor sit amet, <i>consectetuer</i> adipiscing <tt>elit</tt>.</p>
Соседними здесь являются теги <b> и <i>, а также <i> и <tt>. При этом <b> и <tt> к соседним элементам не относятся из-за того, что между ними расположен контейнер <i>.
Для управления стилем соседних элементов используется символ плюса (+), который устанавливается между двумя селекторами. Общий синтаксис следующий.
Селектор 1 + Селектор 2 { Описание правил стиля }
Пробелы вокруг плюса не обязательны, стиль при такой записи применяется к Селектору 2, но только в том случае, если он является соседним для Селектора 1 и следует сразу после него.
В примере 11.1 показана структура взаимодействия тегов между собой.
Пример 11.1. Использование соседних селекторов
HTML5CSS 2.1IECrOpSaFx
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Соседние селекторы</title>
<style>
B + I {
color: red; /* Красный цвет текста */
}
</style>
</head>
<body>
<p>Lorem <b>ipsum </b> dolor sit amet, <i>consectetuer</i> adipiscing elit.</p>
<p>Lorem ipsum dolor sit amet, <i>consectetuer</i> adipiscing elit.</p>
</body>
</html>
Результат примера показан на рис. 11.1.
Рис. 11.1. Выделение текста цветом при помощи соседних селекторов
В данном примере происходит изменение цвета текста для содержимого контейнера <i>, когда он располагается сразу после контейнера <b>. В первом абзаце такая ситуация реализована, поэтому слово «consectetuer» в браузере отображается красным цветом. Во втором абзаце, хотя и присутствует тег <i>, но по соседству никакого тега <b> нет, так что стиль к этому контейнеру не применяется.
Разберем более практичный пример. Часто возникает необходимость в текст статьи включать различные сноски и примечания. Обычно для этой цели создают новый стилевой класс и применяют его к абзацу, таким способом можно легко изменить вид текста. Но мы пойдем другим путём и воспользуемся соседними селекторами. Для выделения замечаний создадим новый класс, назовём его sic, и станем применять его к тегу <h3>. Первый абзац после такого заголовка выделяется цветом фона и отступом (пример 11.2). Вид остальных абзацев останется неизменным.
Пример 11.2. Изменение стиля абзаца
HTML5CSS 2.1IECrOpSaFx
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Изменение стиля абзаца</title>
<style>
h3.sic {
font-size: 140%; /* Размер шрифта */
color: maroon; /* Цвет текста */
font-weight: normal; /* Нормальное начертание текста */
margin-left: 30px; /* Отступ слева */
margin-bottom: 0px; /* Отступ снизу */
}
h3.sic + P {
background: #ddd; /* Цвет фона */
margin-left: 30px; /* Отступ слева */
margin-top: 0.5em; /* Отступ сверху */
padding: 7px; /* Поля вокруг текста */
}
</style>
</head>
<body>
<h2>Методы ловли льва в пустыне</h2>
<h3>Метод последовательного перебора</h3>
<p>Пусть лев имеет габаритные размеры L x W x H, где L - длина льва
от кончика носа до кисточки хвоста, W - ширина льва, а H - его высота.
После чего пустыню разбиваем на ряд элементарных прямоугольников, размер
которых совпадает с шириной и длиной льва. Учитывая, что лев может находиться
не строго на заданном участке, а одновременно на двух из них, клетку для
ловли следует делать повышенной площади, а именно 2L x 2W. Благодаря
этому мы избежим ошибки, когда в клетке окажется пойманным лишь половина
льва или, что хуже, только его хвост.</p>
<h3>Важное замечание</h3>
<p>Для упрощения расчетов хвост в качестве погрешности измерения можно
отбросить и не принимать во внимание.</p>
<p>Далее последовательно накрываем каждый из размеченных прямоугольников
пустыни клеткой и проверяем, пойман лев или нет. Как только лев окажется в
клетке, процедура поимки считается завершенной.</p>
</body>
</html>
Результат данного примера показан на рис. 11.2.
Рис. 11.2. Изменение вида абзаца за счёт использования соседних селекторов
В данном примере текст отформатирован с применением абзацев (тег <p>), но запись h3.sic + P устанавливает стиль только для первого абзаца идущего после тега <h3>, у которого добавлен класс с именем sic.
Соседние селекторы удобно использовать для тех тегов, к которым автоматически добавляются отступы, чтобы самостоятельно регулировать величину отбивки. Например, если подряд идут теги <h2> и <h3>, то расстояние между ними легко регулировать как раз с помощью соседних селекторов. Аналогично дело обстоит и для идущих подряд тегов <h3> и <p>, а также в других подобных случаях. В примере 11.3 таким манером изменяется величина отступов между указанными тегами.
Пример 11.3. Отступы между заголовками и текстом
HTML5CSS 2.1IECrOpSaFx
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Соседние селекторы</title>
<style>
h2 + h3 {
margin-top: -10px; /* Смещаем заголовок 2 вверх */
}
h3 + P {
margin-top: -1em; /* Смещаем первый абзац вверх к заголовку */
}
</style>
</head>
<body>
<h2>Заголовок 1</h2>
<h3>Заголовок 2</h3>
<p>Абзац!</p>
</body>
</html>
Поскольку при использовании соседних селекторов стиль применяется только ко второму элементу, то размер отступов уменьшается за счёт включения отрицательного значения у свойства margin-top. При этом текст поднимается вверх, ближе к предыдущему элементу.
Вопросы для проверки
1. Какие теги в данном коде являются соседними?
<p><b>Формула серной кислоты:</b><i>H<sub><small>2</small></sub>SO<sub><small>4</small></sub></i></p>
- <P> и <I>
- <B> и <I>
- <I> и <SUB>
- <SUB> и <SMALL>
- <I> и <SMALL>
2. Имеется следующий код HTML:
<p><b>Великая теорема Ферма</b></p>
<p><i>X <sup><small>n</small></sup> + Y <sup><small>n</small></sup>
= Z <sup><small>n</small></sup></i></p>
<p>где n — целое число > 2</p>
Какой текст выделится красным цветом с помощью стиля SUP + SUP { color: red; } ?
- «X»
- «Y»
- «Z»
- Вторая «n»
- Вторая и третья «n».
Ответы
1. <B> и <I>
2. Вторая и третья «n».
Селекторы CSS – точечное применение свойств CSS к элементам страницы (тегам)
Заметка: активирована адаптивная версия сайта, которая автоматически подстраивается под небольшой размер Вашего браузера и скрывает некоторые детали сайта для удобства чтения. Приятного просмотра!
22.04.2013
Здравствуйте дорогие подписчики и не менее дорогие гости Site on! Надеюсь, вам были интересны предыдущие статьи раздела HTML + CSS, потому как сегодня скучать точно не придётся, ведь мы рассмотрим такое понятие как селекторы CSS и как с их помощью мы можем сократить нашу разметку HTML, сделав её чище.
Селектор CSS – это тот элемент, к которому мы собираемся применять CSS свойства. Слово «селектор» говорит само за себя, оно обозначает выбор.
p {color: red} div span {background: green} ul li {list-style: none}
Селекторы class и id
В примере выше мы имеем 3 селектора – это p, div span, ul li. То есть весь наш файл стилей состоит из селекторов и их свойств. Наиболее удобно и наглядно, особенно новичкам, брать за селектор имя класса (class) тега или уникальный идентификатор (id) тега. Чтобы присвоить класс или идентификатор какому-либо тегу, мы должны указать их среди атрибутов этого тега. У конкретного тега может быть максимум 1 идентификатор и бесконечное число классов. Пример:
<div>текст в первом диве</div> <div>текст во втором диве</div> <div>текст в третьем диве</div>
На что стоит обратить внимание:
- Классы и идентификаторы можно присваивать любым (всем) тегам.
- Каждый id уникален и не может повторяться в пределах одной страницы, в отличие от классов!
- Один и тот же класс может быть присвоен любым тегам и может повторяться любое количество раз на странице.
- Если мы хотим задать конкретному тегу несколько классов, мы просто задаём их через пробел.
- Имена классов и идентификаторов могут совпадать, при этом кроме имени, ничего общего между ними не будет.
Как обратиться к классу или id в файле стилей (CSS)?
Смотрим пример:
#first {color: red;} /* обращаемся к id с именем first */ .second {color: blue;} /* обращаемся к классу с именем second */ #first .second {color: orange;} /* обращаемся к классу с именем second, ТОЛЬКО если он находится ВНУТРИ тега с идентификатором first */ .first .third {color: grey;} /* обращаемся к классу с именем third, ТОЛЬКО если он находится ВНУТРИ тега с классом first */
В нашем случае последние две инструкции не сработают, так как у нас нет классов, вложенных внутрь тегов с заданными атрибутами. Как вы могли заметить, чтобы обозначить, что мы обращаемся именно к id, нужно перед его именем без пробелов поставить знак решётки (#), если мы обращаемся к классу, то перед именем класса должны поставить точку (.).
Использование классов и идентификаторов очень удобно, но оно увеличивает нашу HTML разметку, в идеале (которого никогда нет) мы вовсе не должны их использовать, вместо них мы будем использовать комбинации и группировки селекторов, о них и будет вся остальная часть статьи, но! Но это совсем не означает, что вы должны полностью отказаться от использования классов и идентификаторов, просто вы должны иметь ввиду, что очень часто вместо создания нового class или id можно обойтись приёмами, описанными ниже и они также могут быть вполне удобны.
В чём различие class и id?
Кроме приведённых выше различий, стоит ещё отметить, что у свойств заданных id приоритет выше, чем у свойств, заданных классу. То есть, если мы напишем:
<style> #first {color: red;} .blue {color: blue;} </style> <div>текст в диве</div>
То цвет текста станет красным, несмотря на то, что класс находится ниже по коду и если бы у них был равный приоритет текст стал бы синим.
По синтаксису: в случаи с классом мы можем выбрать, у какого именно тега должен находиться данный класс, для этого после имени тега БЕЗ пробела мы должны обратиться к классу. Пример:
.myclass {свойства} /* применятся ко всем тегам, которые содержат класс myclass */ div.myclass {свойства} /* применятся только к тегам div, которые содержат класс myclass */
Для id это тоже будет работать, но такая запись лишена всякого смысла, так как id не может повторяться на странице, а значит достаточно просто объявлять id, без тега к которому оно относится:
<style> #super {свойства} /* правильно */ div#super {свойства} /* Неправильно, но работать будет */ </style> <div>текст</div>
Вроде бы осталось только одно неоговорённое отличие, и оно касается темы, которую в ближайшем будущем я не планировал затрагивать на этом блоге – Javascript. Но всё же обязан доложить вам о нём: если вы хотите обратиться к элементу с помощью Javascript, то для этой цели очень удобным будет наличие id у этого элемента. Чтобы обратиться к элементу по его классу в Javascript нет такой встроенной возможности, вам придётся использовать вспомогательные функции + это не всегда кроссбраузерно.
Итог: id и class используем, но в меру, при этом всегда спрашивая себя, а можно ли здесь обойтись без них и насколько это целесообразно.
Родственный селектор
Идём дальше. Из статьи о наследовании в CSS вы уже знаете о двух самых простых видах селекторов, это селектор по тегу (элементу) и по потомку. Давайте освежим вашу память:
div p {color: green;} /* Селектор по потомку */ p {color: red;} /* селектор по тегу */
Но как я уже писал в предыдущей статье, в первом случае CSS свойства применятся ко всем тегам p вложенным на ЛЮБУЮ глубину тега div. А что если мы хотим применить свойства только к прямым наследникам, то есть к первому уровню вложенности:
<div> <p>Прямой наследник (первый уровень)</p> <span> <span> <p>Третий уровень</p> </span> </span> <p>Прямой наследник (первый уровень)</p> <span> <p>Второй уровень</p> </span> <p>Прямой наследник (первый уровень)</p> </div>
В таком случае мы должны использовать так называемый родственный селектор, для его обозначения используется угловая скобка, пробелы можете ставить, можете не ставить, я бы не советовал:
div>p {color: blue;} /* только первый уровень вложенности */ div p {color: blue;} /* абсолютно все параграфы внутри div */
Универсальный селектор
С этим разобрались, у нас на вооружении уже 3 вида селекторов, теперь хочу вам рассказать о весьма необычном селекторе, который выделяется среди всех остальных – это так называемый универсальный селектор, который обозначается звёздочкой (*):
* {margin: 0; padding: 0;}
Так у меня начинается каждый новый проект, советую вам делать также. Универсальный селектор распространяется на все элементы страницы (теги), но имеет нулевой приоритет (ниже только отсутствие приоритета вовсе). Его обычно используют, чтобы перебить CSS свойства, которые браузеры устанавливают по умолчанию для некоторых тегов. Представьте себе, и такое имеет место быть! Достаточно многим тегам браузеры по умолчанию устанавливают свои свойства, например, тегу гиперссылки <a> синий цвет текста и подчёркивание, тегу body они задают поля (padding) и тд. Нам это запоминать, знать и использовать совсем не к чему, поэтому самые банальные свойства мы сразу же убираем с помощью универсального селектора, однако я бы не советовал дописывать в него что-то ещё (или дописывать, но аккуратно), несмотря на наименьший (нулевой) приоритет универсального селектора, он в некоторых случаях всё же может перебить вам другие свойства, так что имейте это в виду.
Кстати говоря, при работе с селекторами, как и при любой работе связанной с вёрсткой макета очень удобно использовать просмотр элементов страницы. Если вы ещё не в курсе таких вещей как Opera Dragonfly, Firebug и веб-инспекторы в целом, то вам без преувеличений срочно нужно прочесть статью по ссылке выше! А кто уже использовал подобные вещи, прошу дальше за мной.
Псевдо-классы
В отличие от классов, псевдо-классы не нужно указывать в HTML разметке, они сами вычисляются браузером. У нас есть 4 статических псевдо-класса и 3 динамических псевдо-класса, без учёта CSS 3, о нём ближе к концу. К статическим относятся ( :first-child, :link, :visited, : lang() ):
<style> p:first-child {color: green;} /* сработает, если p является первым ребёнком своего родителя */ </style> <div> <p>Прямой наследник (первый уровень)</p> <span> <span> <p>Третий уровень</p> </span> </span> <p>Прямой наследник (первый уровень)</p> <span> <p>Второй уровень</p> </span> <p>Прямой наследник (первый уровень)</p> </div>
Результат:
Естественно можно комбинировать селекторы как захотим, например:
div>span p:first-child {color: green;} /*сработает, если p является первым ребёнком своего родителя и находится внутри тега span, который является прямым потомком тега div */
Название представленного выше псевдо-класса говорит само за себя first-child — первый ребёнок.
Следующие два статических псевдо-класса применяются только к тегу гиперссылки (:link, :visited), они применяют CSS свойства в зависимости от того, посещалась данная ссылка конкретным пользователем или нет:
a:link {color: blue;} /* у не посещённых ссылок задаём синий цвет, и по умолчанию они подчёркнуты */ a:visited {color: green; text-decoration: none;} /* у посещённых ссылок текст будет зелёным, убираем подчёркивание */
Псевдо-класс :lang() используется для задания разного стиля оформления в зависимости от языка. В скобочках указывается язык, к которому нужно применить оформление. Это можно использовать, например, для задания разных стилей кавычек в цитатах:
q:lang(de) {quotes: "\201E" "\201C";} /* кавычки для немецкого языка */ q:lang(en) {quotes: "\201C" "\201D";} /* кавычки для английского языка */ q:lang(ru) {quotes: "\00AB" "\00BB";} /* кавычки для русского языка */
Это, пожалуй, единственный из всех возможных видов селекторов, который я никогда не использовал.
Динамические псевдо-классы
Динамические псевдо-классы – это :active, :hover, :focus. Динамические псевдо-классы срабатывают по определённому действию на странице, они работают для всех тегов, а не только для ссылок как многие думают и даже утверждают в своих блогах! Рассмотрим их применение:
p:active {background: red;} /* стиль, который применится к тегу по нажатию на него (клику мышью) */ input:focus {width: 400px;} /* стиль, который применится к элементу, на котором в данный момент фокус (работает, к примеру, для текстовых полей ввода: textarea, input). В данном случае по взятию в фокус, ширина input станет равна 400 пикселей, удобно использовать для красивого эффекта удлинения поля по клику. */ div:hover {background: green;} /* срабатывает по наведению курсора на элемент, в основном применяется для создания красивого эффекта при наведении на ссылки. */
Примените данные стили к нашему примеру выше, и вы сами всё увидите.
Смежные селекторы
Смежные селекторы – это ближайший сосед ниже по коду, не ребёнок! Очень удобный селектор:
<style> div + p {background: green; color: white;} /* Применить свойства к тегу p, если сразу после закрывающегося тега div открывается тег p */ p + span {background: orange;} /* не сработает, так как у нас нет открывающегося тега span, сразу после закрывающегося тега p */ </style> <div> <p>текст в параграфе первого div</p> </div> <p>текст в параграфе ВНЕ div</p> <div> <p>текст в параграфе второго div</p> </div> <span>текст в спане</span> <p>снова параграф вне div</p>
Результат:
Обобщённые смежные селекторы
Обобщённые смежные селекторы действуют точно также как и обычные смежные селекторы, за исключением того, что свойства применяются не только к первому соседу ниже, а ко всем заданным соседям ниже:
<style> div~p{color: green;} </style>
<div>текст в диве</div>
<p>параграф</p> <p>параграф</p> <p>параграф</p>
<span>текст в спане</span>
<p>параграф</p> <p>параграф</p>
<div> <p>параграф в диве</p> <p>параграф в диве</p> </div>
<span>текст в спане</span> <p>параграф</p>
Результат:
Селекторы атрибутов
Селекторы атрибутов позволяют нам обратиться к тегам, имеющим необходимый нам атрибут или даже конкретное его значение:
p[align] {свойства} /* применить ко всем тегам p, у которых есть атрибут align */
p[align="center"] {свойства} /* где значение атрибута align равно center */
p[align^="center"] {свойства} /* где значение атрибута align начинается на center */
p[align*="center"] {свойства} /* где значение атрибута align содержит center */
p[class~="site"] {свойства} /* где site может находиться среди других слов, отделенных пробелами (<p></p>) */
p[class|="site"] {свойства} /* где значение атрибута class состоит только из слова site или начинается им, после чего ставится дефис и пишется остальная часть значения (<p></p> или <p></p>) */
p[class$="site"] {свойства} /* где значение атрибута align заканчивается на site */
CSS 3 псевдо-классы
Вы уже ознакомились со всеми основными селекторами и вам на первых парах этого должно хватить с горкой. Однако в CSS 3 появилось множество новых псевдо-классов, теперь мы можем брать не только первого ребёнка, но и любого другого по счёту, можем идти от обратного, брать не первого, а последнего ребёнка и так далее и тому подобное. Всё это очень удобно и практично, разве что у вас могут возникнуть проблемы со старыми версиями IE. Давайте соберём все силы в кулак и пробежимся по всем оставшимся селекторам, чтобы потом уже вы могли иметь их ввиду при вёрстке собственного макета.
:last-child – аналог :first-child, только берёт не первого, а последнего ребёнка.
:only-child – сработает, если элемент (тег) является единственным ребёнком.
:only-of-type — сработает, если элемент (тег) является единственным ребёнком своего типа.
:nth-child() – обращается к потомкам по их порядковым номерам, можно обращаться ко всем чётным или нечётным (even или odd) числам. Например:
<style> div p:nth-child(5) {background-color: green;} /* Обращаемся к 5 по счёту ребёнку, если он является тегом p. */
div p:nth-child(2n) {background-color: yellow;} /* Обращаемся к каждому второму ребёнку, если он является тегом p. */
div p:nth-child(2n+6) {background-color: red;} /* Обращаемся к каждому второму ребёнку начиная с шестого, если он является тегом p. */ </style>
<div> <p>параграф</p> <p>параграф</p> <p>параграф</p>
<span>текст в спане</span>
<p>параграф</p> <p>параграф</p> <p>параграф</p> <p>параграф</p> <p>параграф</p> <p>параграф</p> </div>
Результат:
:nth-last-child – работает также как и предыдущий, но отчёт начинается с конца.
:first-of-type – первый ребёнок своего типа в рамках прямого родителя.
:last-of-type – последний ребёнок своего типа в рамках прямого родителя.
:empty – сработает для тех тегов, внутри которых нет ни одного символа (без текста).
:not() – делает исключение для заданных элементов. Пример:
<style> p:not(.roll) {color: red;} /* для всех параграфов на странице делаем красный цвет текста, за исключением параграфов с классом roll */ </style>
<p>параграф с классом roll</p>
<p>параграф</p> <p>параграф</p>
<p>параграф с классом roll</p>
Результат:
Управление полями, формами, переключателями и флажками в CSS
:enabled — применяется к доступным элементам интерфейса как формы, кнопки, переключатели и тд. По умолчанию все элементы интерфейса являются доступными.
:disabled — применяется к заблокированным элементам интерфейса как кнопки, формы и так далее. Элементы интерфейса являются заблокированными, если к ним в HTML добавить атрибут disabled или в XHTML disabled=”disabled”.
:checked – применяется к элементам интерфейса типа переключатели (radio) и флажки (checkbox), когда они находятся во включённом положении.
Псевдо-элементы
Псевдо-элементы, аналогично псевдо-классам вычисляются браузером автоматически, нам об этом заботиться не нужно. Чтобы не путать псевдо-элементы с псевдо-классами в спецификации CSS 3 было решено использовать двойное двоеточие, вместо одинарного, как было в CSS 2. Поэтому в Интернете вы можете встретить псевдо-элементы как с одинарным двоеточием так и с двойным – и тот и тот вариант верен. Однако для лучшей совместимости с IE рекомендуют использовать одинарное двоеточие.
:first-line – первая строка внутри блочного или табличного элемента.
:first-letter – первая буква внутри блочного элемента.
:before и :after – используются чтобы с помощью CSS вставить содержимое до или после элемента, к которому они относятся, лично я ими не пользовался, поэтому сильно расписывать не буду. А как часто вы используете данные псевдо-элементы в своих проектах? Можете поделиться своим опытом в комментариях к данной статье.
Итоги: теперь вы знаете и можете использовать всю мощь каскадных таблиц стилей, однако это не значит, что нужно сразу ринуться верстать макеты сайтов, используя как можно больше изученных сегодня селекторов, псевдо-классов и псевдо-элементов. Я перечислил все возможные инструменты, а вы должны выбрать лишь самое нужное для себя.
Преимущества оптимизации HTML за счёт CSS
Суть всего написанного выше отчасти заключается в том, чтобы отказаться от повсеместного использования атрибутов class и id в HTML, тем самым возложив всё на плечи могучих таблиц стилей.
Внешние файлы стилей, как и внешние файлы Javascript отлично кэшируются, а это значит, что зайдя первый раз на любую страницу вашего сайта, браузер пользователя запоминает эти файлы и более их не скачивает, в отличие от самой страницы сайта, то есть вашей HTML разметки, картинок и текста, которую браузер загружает снова и снова. Тоже самое касается и поисковых систем, им вообще нет дела до ваших внешних файлов, но вот до объёма и содержания вашей HTML разметки им дело есть. Поисковым системам приходится сканировать всю структуру страницы и в ваших же интересах помочь им в этом, сосредоточить их усилия на контенте, а не на громоздкой стене разметки состоящей из кучи классов и идентификаторов или того хуже – Javascript обработчиков событий и CSS стилей прямо в атрибутах тегов (и такое до сих пор бывает).
Вы можете со мной поспорить, мол, мы можем заставить клиентский браузер скачивать себе в локальную среду все подключаемые файлы, картинки, закэшировать всю страницу целиком и так далее и тому подобное. На таком фоне подобная мелочь совсем теряется, но так или иначе максимально сократив HTML разметку, вы только выигрываете, при этом ничего не потеряв, кроме возможной привычки.
Подытожим: благодаря оптимизации и сокращению HTML мы имеем совсем небольшой выигрыш в скорости загрузки сайта и в SEO (поисковой оптимизации), а также более чистый код.
Пожалуйста, оцените эту статью
Средняя оценка: 4.87 из 5 (проголосовало: 283)Статья оказалась вам полезной? Подпишитесь, чтобы не пропустить новые!
Вы можете помочь развитию проекта, сделав всего 1 клик:
Спасибо!Селекторы CSS и их применение в автоматизации тестирования Программного Обеспечения
Всем добра!Данную тему мы уже раскрывали на вебинаре, который проводил наш преподаватель, но решили дополнить чуть текстом (да и многим, как оказалось, так удобнее). В общем представляем статью на тему «Селекторы CSS», которую Павел Попов прорабатывал в рамках нашего курса «Автоматизация в тестировании».
Поехали.
Каждый курс или статья для начинающих автоматизаторов рассказывает об удобном и универсальном средстве поиска элементов Web-страницы, как XPath. Данный вид локаторов на элемент был создан в 1999 году для указания на элементы в XML файлах. С помощью встроенных функций XPath стал очень популярным инструментом поиска элементов на Web-странице. Если HTML код вашего приложения выглядит как-то так:
…
<form class=“form_upload>
<div>
<div class=“row_element_3 row tile_fixed”>
<div class=“button_cell wrapper_tile”>
<button type=“submit” class=“button_submit wrapper_button”>Нажми меня</button>
</div>
</div>
</div>
</form>
…
и вы не можете найти достойный XPath для кнопки “Нажми меня”, не стоит сразу бежать в сторону разработчика с просьбой о помощи. Есть отличная возможность воспользоваться CSS селектором, он будет выглядеть так:
.button_submit
Добро пожаловать в мир CSS.
Принято считать, что в CSS селекторах все завязано на классы. Это не совсем так, но если Web приложение использует “оптимизатор” или “обфускатор” HTML кода, и выглядит вот так:
<form class=“afhfsdh__”>
<div>
<div class=“hfgeyq fjjs qurlzn”>
<div class=“fjdfmzn fjafjd”>
<button type=“submit” class=“ajffalf wjf_fjaap”></button>
</div>
</div>
</div>
</form>
…
(все названия css классов уменьшены с помощью оптимизатора)
, то получить короткий CSS селектор не удастся — как правило, после каждого нового билда css классы меняются на новые. Но все равно, CSS селектор может оказаться проще и в этом случае: css: form button[type=‘submit’]
, вместо XPath: //form//button[@type=‘submit’]
Допустим, что оптимизаторы HTML у нас не установлены и разработчики не планируют его использовать на проекте (проверьте этот факт!).
Как вы могли уже догадаться, символ. используется вместо слова class и будет искать вхождение данного класса в любом элементе, в независимости от количества классов у этого элемента.
Смотрите:
<form class=“form_upload>
<div>
<div class=“row_element_3 row tile_fixed”>
<div class=“button_cell wrapper_tile”>
<button type=“submit” class=“button_submit wrapper_button”></button>
</div>
</div>
</div>
</form>
css для элемента button: .button_submit
, при этом класс .wrapper_button
указывать необязательно, но если он нужен для указания на наш класс, мы можем его добавить сразу после указания первого css класса: css: .button_submit.wrapper_button
. Порядок классов роли не играет, поэтому их можно поменять местами:
.wrapper_button.button_submit .
Следующим незаменимым помощником в поиске HTML элементов являются Теги. Написать css селектор, указывающий на тег button очень просто, тем более, что он уже был написан в этом предложении. CSS селектор для button –
css: button.
И ничего больше указывать вам не требуется, если ваша цель — это привязка к тегу. Совмещая теги и классы получаем::
button.button_submit
и это также является css селектором к нашему элементу.
Помимо тегов, атрибуты также помогают уникально идентифицировать элемент на странице. Часто разработчики создают дополнительные атрибуты вместо добавления новых “айдишников”, например, могут создавать дополнительные атрибуты data-id или auto-id у каждого элемента, с которым планируется дальнейшее действие. К примеру, разработчики могут добавить атрибут data-id
к нашей кнопке button. Тогда к атрибутам с помощью css селектора можно обратиться через фигурные скобки: [data-id=‘submit’]
. Дополнительно, вы можете не указывать значение атрибута после знака равно [data-id]
. Такой селектор найдет вам все элементы, у которого существует атрибут data-id
с любым значением внутри. Вы также можете указать атрибут class для поиска нашей кнопки: [class=‘button_submit’]
, но в CSS, как вы уже знаете, можно полениться и написать так: .button_submit
. Соединять все вместе также достаточно просто:
button[type=‘submit’].button_submit
тег атрибут класс
Но это большая удача, если нам удается находить элемент, используя селектор с указанием только одного элемента, как, например, использовать атрибут [data-id] который однозначно находит один элемент на странице. Очень часто нам приходится использовать предков элемента, чтобы найти потомка. И это в CSS тоже возможно сделать достаточно просто:
<form class=“form_upload>
<div>
<div class=“row_element_3 row tile_fixed”>
<div class=“button_cell wrapper_tile”>
<button type=“submit” class=“button_submit wrapper_button”></button>
</div>
</div>
</div>
</form>
css:form > div > div > div > button.button_submit
и знак
>
позволяет найти элемент исключительно у предка внутри. Но писать все элементы ненужно, так как в CSS есть возможность поиска во всех потомках, этот символ — пробел “ “
. Используя данный указатель мы можем быстро найти элемент внутри формы:Было: css: form > div > div > div > button.button_submit
Стало: css: form button,button_submit
Удобно также находить следующего “родственника” через предыдущего. Дополним наш пример еще одним span
:
<form class=“form_upload>
<div>
<div class=“row_element_3 row tile_fixed”>
<div class=“button_cell wrapper_tile”>
<div class=“content”></div>
<span data-id=“link”>Ссылка</span> <!-- элемент с атрибутом data-id -->
<button type=“submit” class=“button_submit wrapper_button”> <!-- искомая кнопка --></button>
</div>
</div>
</div>
</form>
[data-id=‘link’] + button
найдет button
, у которого выше на один уровень есть родственник с атрибутом data-id=”link”
. Этим указателем можно пользоваться, когда у предыдущего элемента есть id или уникальный атрибут, а у элемента, который находится следующим после нужного, таких идентификаторов нет. Итак, с помощью символа + css селектор найдет следующего родственника.NOTE:
div + span[data-id=‘link’] + button
Дополнительно вы можете собирать “паровозик” из следующих элементов с использованием указателя +, но не советую это делать из-за возможного изменения местонахождения элементов.
Не стоит упускать вариант поиска по части атрибута. Делается это просто: button[class*=‘submit’]
— из длинного названия класса button_submit
мы берем только правую часть submit
и добавляем к знаку = символ *. Также можно найти по слову cell
из значения класса: div[class*=‘cell’]
.
Есть еще одна особенность css селекторов, которая позволит найти вам все ссылки или расширения файлов, это ^=
и $=
, но такая задача стоит не так часто, как поиск по вхождению значения у атрибута.
a[href^=“https:”]
— найдет все ссылки, которые начинаются с https,a[href$=“.pdf”]
— найдет все ссылки, которые заканчиваются на .pdf.
Немного о том, как найти потомков с одним и тем же тегом у предка. Начнем, как всегда, с примера:
<div class=“tiles”>
<div class=“tile”>…</div>
<div class=“tile”>…</div>
</div>
Как найти второй
div class=“tile”
у div class=“tiles”
? Варианта два:div > div:nth-of-type(2) div > div:nth-child(2)
Но в чем различие между этими двумя селекторами? Дополним пример:
<div class=“tiles”>
<a class=“link”>…</a> <!—1—>
<div class=“tile”>…</div><!—2—>
<div class=“tile”>…</div><!—3—>
</div>
css 1 вариант:
div > div:nth-of-type(2)
css 2 вариант:
div > div:nth-child(2)
Теперь эти селекторы ведут на два разных элемента. Прежде чем идти далее, попробуйте догадаться, какой селектор ведет на какой элемент?
Разгадка:
первый селектор будет указывать на строчку номер 2, тогда как второй селектор будет указывать на строчку номер 3. nth-child
ищет второй div
, который является потомком родителя . Второй
<div>у элемента
<div class=“tiles”>это третья строка. В свою очередь
nth-of-type
ищет второй элемент у родителя<div class=“tiles”>, который должен являться тегом
div, это строка номер два.
Есть правило, которое позволяет упростить работу с селекторами в ситуации, когда вам нужно найти конкретный элемент: использовать nth-of-type
везде, где это возможно. Если вы разобрались с примером выше, рекомендую вам всегда обращать внимание на количество одинаковых элементов у предка, используя nth-child
, и тогда вам будет неважно, куда поместят ссылку
<a>: наверху, между
<div>или внизу блока, всегда селектор
div:nth-child(2)
будет все равно указывать на нужный элемент – второй элемент div внутри блока.Была опущена еще одна функция поиска элемента по id. Вы уже знаете, что поиск по любому из атрибутов осуществляется с использованием указания квадратных скобок [attribute=“value”]
и для нашего случая мы можем найти элемент так [id=“value”]
. А что если есть существует более быстрый способ поиска по id элемента?
#value. “#” - указатель, что поиск осуществляется по id.
Используя все приобретенные навыки попробуйте написать селектор для кнопки
<button>
Отправить
…
<div>
<div class=“tile_wrapper tile content”>
<div class=“row row_content”>
<div class=“outline description__on”></div>
<div class=“outline description__off button_send hover_mouse”>
<button class=“outline button_send”>Отправить</button>
</div>
</div>
</div>
</div>
Будем рады увидеть ваши комментарии и варианты в комментариях тут или обсудить это на очередном открытом уроке, который пройдёт у нас 13-го марта.
Спасибо!
Что вы не знали о селекторах CSS? / Sandbox / Habr
Всем привет, хабрчане.Сегодня CSS окружает нас вокруг, и даже маломайский программист должен понимать его.
Самыми используемыми являются старые добрые #id и .class они знакомы всем, кто хоть раз работа с CSS.
На этом конечно мир Селекторов далеко не ограничивается. Я уже довольно давно работаю с CSS и хочу поделится как можно большим количеством полезных селекторов. Все они определяют стиль того или иного объекта.
CSS Selectors
Объясняю многие селекторы применимо к указанному примеру.
.class
(Пр. .main) Данный селектор объединяет все элементы с классом «main». Родился он давно и активно учувствует в разработке.#id
(Пр. #Block_Form) Этот селектор объедение элементы с id=«Block_Form» В чем скажите разница между .class и #id — а разницу можно понять на примере: то что ПАСПОРТНЫЙ НОМЕР = id, ФАМИЛИЯ = class. Также немало важно то, что — Идентификатор (id) можно вызвать из скрипта используя функцию GetElementById, в отличие от класса.Класс может быть использован многократно, идентификатор же должен быть уникальным.
*
Выбирает, объединяет все элементы(Пр. *)
{
background-color:yellow;
})
element
(Пр. p ) Объединяет все элементы тега p.element,element
(Пр. div,p) Объединяет все элементы div и все элементы p.
Так же в эту группу можно выделить похожие селекторы:
element element
(Пр. div p) Выбирает все элементы p внутри div.element>element
(Пр. div>p) Объединяет все p для которых родителем выступает div.element+element
(Пр. div+p) Объединяет все p которые расположены сразу после div.[attribute]
(Пр. [target]) Объединяет все элементы с атрибутом target[attribute=value]
(Пр. [target=_blank]) Объединяет все элементы с заданным target=»_blank»[attribute~=value]
(Пр. [title~=Apple]) Объединяет все элементы, которые в своем title содержат «Apple»[attribute|=value]
(Пр. [class|=top]) Объединяет все элементы с атрибутом class начиння с «top»Все теги написаны были без «<>».
Дальше считаю обязательно нужно показать именно эти селекторы, так как они являются очень важными и крайне часто используются в решении многих задач — от Простых анимашек с наведением курсора, оформлением ссылок, картинок и прочего до более глобальной цели уменьшения кода в целом.
Так же их называют Псевдокласы:
:link
(Пр. a:link) Объединяет все ссылки, которые еще не посещались:visited
(Пр. a:visited) Объединяет все ссылки, которые пользователь уже успел посетить:active
(Пр. a:active) Псевдокласс :active определяет стиль для активной ссылки. Активной ссылка становится при нажатии на нее.:hover
(Пр. a:hover) Когда проводишь мышкой, ссылка может менять стиль:focus
(Пр. input:focus) Изменяет стиль при фокусировке. на практике часто используется для подсветки полей формы при фокусировке на нем:first-letter
(Пр. p:first-letter) Определяет стиль для первого символа в тексте элемента:first-line
(Пр. p:first-line) Определяет стиль первой строки. Использую для изменения цвета текста, цвета фона и шрифта, но как показывают народные хабрумельцы на этом его функции не ограничиваются:first-child
(Пр. p:first-child) Что бы просто объяснить — применяет стилевое оформление к первому дочернему элементу своего родителя. В примере если р есть первым элементом своего родителяДальше идут два очень интересных класса:
:before
(Пр. p:before):after
(Пр. p:after)Они применяются в тех случаях, когда — нужно отобразить нужный контент до или после содержимого элемента, к которому он добавляется. Работает совместно со свойством content:. Так же я их использую как дополнительные элементы вместо div, в таком случае нужно прописывать content:»»;. Также нужно помнить о том, что при добавлении :before к блочному элементу, значение свойства display может быть только: block, inline, none, list-item. Все остальные значения будут трактоваться как block. При добавлении :before к встроенному элементу, display ограничен значениями inline и none. Все остальные будут восприниматься как inline.
:before наследует стиль от элемента, к которому он добавляется.
:lang(language)
(Пр. p:lang(it)) Довольно простой, но порой нужный элемент — для примера: Определяет стиль каждого p с атрибутом lang, значение которого начинается с «it»Селекторы CSS3
Данные селекторы вызывают большой интерес, так как они мало кем используются и, конечно, хочется разобраться как ими пользоваться, поэтому буду приводить примеры. Также в данной группе селекторов в многострадальном IE8 и раньше DOCTYPE должен быть объявлен.
element1~element2
(Пр. p~ul)p~ul
{
background:red;
}
Устанавливает цвет фона для всех ul элементов, которые предшествуют p с таким же родителем. Грубо говоря — на этом примере, красным будет бэкграунд только у тех «списков» которые стоят после родителя тега р.<div>A div element.</div>
<ul>
<li>Item </li>
<li> Item </li>
<li> Item </li>
</ul>
— в этом случае ничего не произойдет, а в<p>Another</p>
<ul>
<li>Item </li>
<li> Item </li>
<li> Item </li>
</ul>
а в этом случае поля Айтемов будут иметь бэк-цвет — красный.
[attribute^=value]
(Пр. a[src^=«https»]) По примеру определяет стиль каждого a для которого значение элемента src начинающегося с «https». Вот еще пример:<html>
<head>
<style>
[class^="test"]
{
background:#ffff00;
}
</style>
</head>
<body>
<div>item1</div>
<div> item2</div>
<div> item3</div>
<p> item4</p>
</body>
</html>
Проще говоря – данный селектор дает возможность установить цвет фона на всех div элементов, которые имеют значение атрибута класса, начинающихся с «тест» – а именно item3, item4.
[attribute$=value]
(Пр. a[src$=».pdf»]) Выбирает каждый тег a, для которого SRC значение атрибута заканчивается на «. PDF. И вот еще один наглядный пример:<html>
<head>
<style>
div[class$="test"]
{
background:red;
}
</style>
</head>
<body>
<div> Item1</div>
<div> Item2</div>
<div> Item3</div>
<p> Item4 </p>
</body>
</html>
На этом примере очень хорошо будет видно использование данного селектора, а именно в Красный цвет перекрасятся Item1 (по тому что класс заканчивается на _test) и item3.
[attribute*=value]
(Пр. a[src*=«w3schools»]) Выбирает каждый тег a, для которого значение атрибута SRC содержит подстроку «w3schools».<html>
<head>
<style>
div[class*="test"]
{
background:red;
}
</style>
</head>
<body>
<div>item1</div>
<div> item2</div>
<div> item3</div>
<p> item4</div>
</body>
</html>
В этом примере результатом будут закрашенные строки item1, item3, item4.
Дальше перейдем к псевдоклассам
:first-of-type
(Пр. p:first-of-type) Задает правила стилей для первого элемента в списке дочерних элементов своего родителя.:last-of-type
(Пр. p:last-of-type) Соответственно задает правила стилей для последнего элемента в списке дочерних элементов своего родителя.:only-of-type
(Пр. p:only-of-type) А вот этот применяется к дочернему элементу указанного типа, только если он единственный у родителя. Аналогично как :first-of-type:last-of-type или :nth-of-type(1):nth-last-of-type(1).:only-child
(Пр. p:only-child) Такой элемент применяется по примеру к дочернему элементу p, только если он единственный у родителяСледующие два можно также неплохо использовать для определенной последовательности – нечетные (odd), четные(even) или число(1,2,3… или выражения 2n+1), заданные в (Х):
:nth-child(n)
(Пр. p:nth-child(2)) Для каждого, который является вторым дочерним элементом у родителя.
:nth-last-child(n)
(Пр. p:nth-last-child(2)) Тот же смысл, что и у предыдущего, кроме того, что отсчет ведется не от первого элемента, а от последнего.:nth-of-type(n)
(Пр. p:nth-of-type(2)) Используется для добавления стиля к элементам указанного типа на основе нумерации. Например, для картинок у заглавия применить со значением Float: -left or –right.:nth-last-of-type(n)
(Пр. p:nth-last-of-type(2)) Тоже, что и предыдущий, но отсчет ведется не от первого элемента, а от последнего.:last-child
(Пр. p:last-child) Данный селектор задает стилевое оформление последнего элемента своего родителя.Также стоит выделить:
:root
(Пр. :root) Такой селектор определяет корневой элемент документа, иначе говоря — .:empty
(Пр. p:empty) Определяет пустые элементы — без каких-либо дочерних элементов, текста или пробелов.:target
(Пр.#news:target) Грубо говоря – это определение на основе целевого элемента. В примере определение текущего id — #news element. Используется для URL.:enabled
(Пр. input:enabled) Применяется к формам, как доступ к доступным (не заблокированным — disabled) элементам форм, простите за тавтологию.:disabled
(Пр. input:disabled) Иначе говоря – применимо к стилю заблокированных элементов формы.:checked
(Пр. input:checked) Данный псевдокласс применим к элементам интерфейса, таким как переключатели (checkbox) и флаги (radio), когда они включены, конечно же.:not(selector)
(Пр. :not(p)) На примере стиль применяется ко всем элементам, которые не p. В качестве селектора могут быть псевдоклассы, теги, идентификаторы, классы и селекторы атрибутов.Ура. На этом данный топик исчерпан, все денные подготовлены на основе личного опыта и конечно же официальных документаций. Статья подготовлена за 2 дня. Будут вопросы – задавайте.
Количественные CSS селекторы / Habr
Вам когда-нибудь хотелось прямо в CSS коде посчитать, в меню 4 элемента или 10? Для четырех задать им ширину по 25%, а если набралось десять — прижать их друг к другу и уменьшить отступы?Как выяснилось, CSS умеет работать с разным количеством элементов, позволяя избавиться от головных болей и лишнего кода на js.
Динамичный контент
Респонсив дизайн обычно ассоцируется с одной переменной — пространством. Когда мы тестируем респонсив сетки, мы берем какой-то объем контента и смотрим, сколько места он займет, как это выглядит и куда он влазит, а куда нет. То есть, контент считается константой, а пространство — переменной.
Media query являются основой респонсив дизайна, так как позволяют размечать границы, переходя которые одна сетка меняется на другую. Однако, на расстановку элементов и пространство вокруг них может влиять не только размер экрана, но и собственно сам контент.
Точно так же, как посетители сайта могут пользоваться множеством устройств с разными размерами экранов, ваши контент-менеджеры и редакторы могут добавлять или удалять контент. У них даже для этого целые CMS есть. Именно поэтому дизайны страниц в фотошопе потеряли свою актуальность — в них всегда фиксированная ширина экрана и всегда фиксированный контент.
В этой статье я опишу технику создания CSS, лишенного проблем с количеством (подсчётом) элементов. Достигается это за счёт специально оформленных селекторов. Я буду применять их в контесте решения классической проблемы: как разделить вёрстку элементов в горизонтальном меню сайта, когда в нём мало и много элементов. Например, как добиться того, что при 6 и более пунктах меню элементы имели стиль display: inline-block, а при меньшем количестве — display: table-cell.
Я не буду использовать шаблонизацию или js, мне даже не понадобятся прописывать классы у элементов меню. Техника использования только CSS селекторов соответствует принципу разделения интересов, согласно которому, контент (HTML) и отображение (CSS) имеют ясно обозначенные роли. Разметка — это работа CSS и, по возможности, одного только CSS.
Демо доступно на CodePen и еще будет упоминаться по ходу статьи.
Чтобы упростить понимание, я буду использовать картинки с кальмарами вместо HTML тегов. Зеленые кальмары будут за элементы, которые попадают под конкретный селектор, красные — за те, которые не попадают, а серые будут значить, что элемента не существует.
Счёт
Чтобы узнать количество элементов, их нужно посчитать.Прим. пер
Капитан
CSS не даёт явного «подсчитывающего API», но мы можем решить эту проблему в обход, комбинируя селекторы нужным образом.Считаем до одного
Селектор :only-child срабатывает на элементах, которых всегда одна штука. По сути, это позволяет нам «применить стили ко всем дочерним элементам конкретного элемента, если суммарно их ровно 1». Это единственный простой селектор, который можно описать как «подсчитывающий» (кроме, конечно, похожего на него :only-of-type).
В описанном ниже примере я использую :only-of-type, чтобы применить стили ко всем кнопкам, которые являются единственными чилдами-кнопками среди их соседей.
button {
font-size: 1.25em;
}
button:only-of-type {
font-size: 2em;
}
Важно понимать, что очередность строк здесь имеет ключевое значение. Кроме этого, полезно видеть этот код с точки зрения селекта «меньше-чем-два»:
Аналогично, мы теперь можем сделать селект «больше-чем-один», используя отрицание.
/* "больше-чем-один" будут иметь уменьшенный размер шрифта */
button {
font-size: 2em;
}
button:not(:only-of-type) {
font-size: 1.25em;
}
N элементов
Применять стили, основываясь на «больше-чем-один» и «меньше-чем-два» это ловкий трюк, но нам нужен более гибкий инструмент, позволяющий оперировать с любым числом. Мы хотим использовать селекты “больше или равно N” для любого N. Кроме этого, хочется иметь селект «ровно 745» или «суммарно ровно 6».
Для этого у нас есть селектор :nth-last-child(n), в который мы параметром передаем любое число. Он позволяет отсчитать столько-то элементов назад от конца списка. Например, :nth-last-child(6) выберет элемент, который является шестым с конца среди своих соседних элементов.
Всё становится интереснее, когда мы совмещаем :nth-last-child(6) и :first-child, в результате получая все элементы, которые являются шестыми с конца и при этом первыми с начала.
li:nth-last-child(6):first-child {
/* зеленый кальмар */
}
Если такой элемент существует, это будет значить, что у нас ровно 6 элементов. Таким образом, я написал CSS код, который может сказать, сколько элементов я вижу перед собой.
Осталось теперь воспользоваться этим одновременно «шестым с конца и первым с начала» элементом, чтобы еще и поселектать все остальные 5 элементов. Для этого я воспользуюсь общим соседним комбинатором.
Если вы не знакомы с этим комбинатором, то объясняю, ~ li в селекте li:nth-last-child(6):first-child ~ li значит «любой li, который идёт после li:nth-last-child(6):first-child». В нашем случае, элементы будут иметь зеленый цвет шрифта, если их ровно 6 штук.
li:nth-last-child(6):first-child,
li:nth-last-child(6):first-child ~ li {
color: green;
}
Больше или равно 6
Селектать фиксированное количество, будь то 6, 19 или 653 — не очень-то полезно, так как подобная необходимость очень редка. Это как в media queries — не очень удобно использовать фиксрованную ширину вместо min-width или max-width:
@media screen and (width: 500px) {
/* стили для ширины вьюпорта ровно в 500px */
}
В навигационном меню я хочу переключать стили с границей, основанной на количестве элементов, например, поменять нужные стили, если у меня 6 и больше элементов (а не ровно шесть).
Вопрос в том, как сделать такой селектор? и это вопрос смещений.
Параметр n+6
Селектор :nth-child() может принимать параметром не только число, но и формулу “n + [число]”. Например, :nth-child(n+6) будет применён ко всем элементам, начиная с шестого.
Хоть этот селектор и является мощным инструментом сам по себе, он не позволяет оперировать с количеством. Он применится не тогда, когда у нас больше шести элементов, а просто к элементам, у которых номер больше пяти.
Чтобы обойти эту проблему, нам нужно создать такой селект, который выделит все элементы, кроме последних пяти. Используя обратный к :nth-child(n+6) селект :nth-last-child(n+6) мы сможем выделить все элементы «от с шестого с конца и до самого первого с начала».
li:nth-last-child(n+6) {
/* здесь стили */
}
Такой селект отсекает последние пять элементов от набора любой длины, что означает, что если у вас меньше шести элементов, то в селект ничего и не попадет.
Если же в списке шесть или больше элементов, нам остаётся прибавить к селекту оставшиеся пять элементов. Это легко — если элементов больше шести, то срабатывает условие nth-last-child(n+6), и комбинируя его с «~» мы сможем поселектать все нужные нам элементы.
Такая вот короткая запись и является решением нашей проблемы:
li:nth-last-child(n+6),
li:nth-last-child(n+6) ~ li {
/* здесь стили */
}
Разумеется, тут может быть любое положительное целое число, даже 653,279.
Меньше или N
Как и в предыдущем примере с :only-of-type, селектор можно использовать в обе стороны, и как «больше или равно N» и как «меньше или равно N». Какой вариант вы будете использовать? Зависит от того, какую сетку вы будете считать основной.
В случае «Меньше или N» мы берем n с минусом и добавляем условие :first-child.
li:nth-last-child(-n+6):first-child,
li:nth-last-child(-n+6):first-child ~ li {
/* здесь стили */
}
В результате, использование «-» меняет направление селекта: вместо того, чтобы считать от начала и до шести, отсчёт будет идти от конца до шести. В обоих случаях, шестой элемент будет включён в селект.
nth-child против nth-of-type
Заметьте, что в предыдущих примерах я использовал :nth-child() и :nth-last-child(), а не :nth-of-type() с :nth-last-of-type(). Так как я селектал теги и правильными потомками могут быть только они, :last-child() и :last-of-type() оказываются одинаково результативны.
Обе группы селектов :nth-child() и :nth-of-type() имеют свои преимущества, исходя из того, чего вы хотите добиться. Так как :nth-child() не привязан к конкретному тегу, описанную выше технику можно применять к смешанным дочерним элементам:
<div>
<p>...</p>
<p>...</p>
<blockquote>...</blockquote>
<figure>...</figure>
<p>...</p>
<p>...</p>
</div>
.container > :nth-last-child(n+3),
.container > :nth-last-child(n+3) ~ * {
/* здесь стили */
}
(Обратите внимание, чтобы не привязываться к тегам, я использую универсальный селектор. :last-child(n+3) ~ *. В этом случае, он обозначает «любой элемент любого тега, следующий за :last-child(n+3).»
С другой стороны, преимущество :nth-last-of-type() в том, что вы можете селектать элементы с одним тегом среди множества других соседних. Например, можно посчитать количество тегов <p>, несмотря на то, что они в одной куче с <div> и <blockquote>.
<div>
<div>...</div>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<blockquote>...</blockquote>
</div>
p:nth-last-of-type(n+6),
p:nth-last-of-type(n+6) ~ p {
/* здесь стили */
}
Поддержка браузерами
Все используемые в статье селекторы CSS2.1 и CSS3 поддерживаются в Internet Explorer 9 и выше, а так же все современные мобильные и десктопные браузеры.
Internet Explorer 8 неплохо поддерживает большинство селектов, но задуматься о полифилле на js не помешает. В качестве альтернативы, можно расставить специальные классы для старых версий IE и приписать их к своим селекторам. В случае с навигационным меню, код будет выглядеть примерно так:
nav li:nth-last-child(n+6),
nav li:nth-last-child(n+6) ~ li,
.lt-ie9 nav li {
display: inline-block;
/* и т.д. */
}
В реальном мире
Предположим, наше навигационное меню принадлежит сайту с CMS. В зависимости от того, кто его наполняет и использует, в меню будет разное количество элементов. Кто-то старается не усложнять и ему хватает «Home» и «About», а кто-то хочет запихать в меню всё, что есть у него на сайте.
Создавая стили, учитывающие разные сетки для разного количества элементов в меню, мы делаем вёрстку более стройной и подходящей для самых разных форматов — какой бы ни был контент, у нас всё учтено.
Поздравляю, теперь в вашем CSS арсенале есть умение оперировать количеством элементов.
Контент-независимый дизайн
Респонсив дизайн решает одну важную проблему: он позволяет комфортно расположить один и тот же контент на множестве разных устройств. Было бы неприемлемо видеть разный контент только потому, что у тебя экран неправильного размера. Так же и неприемлемо диктовать дизайнеру, под сколько пунктов меню должен быть заточен сайт. «Не рисуй так, у нас вся сетка поедет, если будет столько элементов».
Какую форму примет контент и сколько его будет в конкретный момент времени — никто не знает. И мы не можем всегда полагаться на скрипты или обрезание текста, это неправильно. Правильно — быть независимым от количества контента и создавать для этого нужные механизмы и инструменты. Количественные селекторы это просто одна из идей для этого.
Веб дизайн это всегда изменчивость, гибкость и неопределенность. В нём скорее не знаешь, чем знаешь. Он уникален тем, что представляет с собой вид визуального дизайна, который не определяет формы, а предвидит, какие формы может что-то принять. Для кого-то это неприемлемо и непонятно, но для вас и меня это вызов и удовольствие.