Иногда нужно выбрать элемент не по тегу, классу или id, а по тому, какой у него атрибут - например, все ссылки с target или все чекбоксы. Для этого в CSS есть селекторы по атрибуту: квадратные скобки после селектора проверяют, есть ли атрибут вообще, или требуют, чтобы его значение точно совпадало с указанным.
Попробуй прямо в этом окне: первая ссылка останется обычного синего цвета - у неё нет атрибута target, значит правило a[target] её не касается. А вторая ссылка станет оранжевой, потому что target у неё есть, и неважно, какое у него значение. Обводку получит только чекбокс - его type в точности равен "checkbox", а не текстовое поле.
[attr] - проверка, что атрибут есть
Селектор в квадратных скобках без знака равенства проверяет только одно: есть ли у элемента такой атрибут вообще. Какое у него значение - неважно, подойдёт любое, даже пустая строка.
a[target] { color: tomato; } - выберет любую ссылку с атрибутом target, будь то target="_blank" или target="_self".
target { color: tomato; } - без квадратных скобок это уже не селектор по атрибуту, а попытка выбрать несуществующий тег <target>. Такое правило не найдёт на странице ничего.
[attr=value] - точное значение атрибута
Если внутри квадратных скобок после знака равенства указать конкретное значение, селектор выберет только те элементы, у которых атрибут равен именно этой строке целиком - частичное совпадение не считается. Значение можно писать в кавычках или без них, но кавычки обязательны, если в значении есть пробел или другие небуквенные символы.
input[type="checkbox"] { outline: 3px solid dodgerblue; } - сработает только для полей с type, равным ровно "checkbox".
[data-role=nav item] { } - значение с пробелом без кавычек. Браузер не поймёт, где заканчивается значение атрибута, и просто отбросит всё правило как ошибочное - остальные правила в том же <style> при этом продолжат работать как обычно.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Путать [attr] и [attr=value] | [attr] выбирает по факту наличия атрибута с любым значением, а [attr=value] - только при точном совпадении значения. Это разные селекторы с разным результатом | Использовать [attr], когда важен только факт наличия, и [attr=value], когда важно конкретное значение |
| Забыть кавычки вокруг значения с пробелом или спецсимволом | Браузер не может разобрать такое значение и отбрасывает всё правило целиком, а не только проблемную часть | Всегда брать в кавычки значения, если не уверен, что это одно простое слово из букв и цифр |
| Считать, что регистр значения ВСЕГДА важен (или ВСЕГДА неважен) | На самом деле это зависит от конкретного атрибута: class, id и data-* сравниваются с учётом регистра, а вот перечислимые атрибуты самого HTML, например type у input, HTML сравнивает без учёта регистра - и это правило CSS просто наследует от HTML | Для своих (data-*, class) атрибутов регистр важен всегда; для встроенных HTML-атрибутов вроде type - можно писать в любом регистре, но лучше придерживаться того, как значение написано в HTML |
| Писать [attr] без квадратных скобок, как обычное слово | Без скобок браузер попытается найти тег с таким именем, а не атрибут, - в 99% случаев такого тега не существует, и правило ничего не находит | Не забывать квадратные скобки - они и есть синтаксис селектора по атрибуту |
Шпаргалка
| Селектор | Что выбирает |
|---|---|
| [attr] | Любой элемент, у которого есть такой атрибут, независимо от значения |
| [attr="value"] | Элемент, у которого атрибут равен именно этому значению целиком |
| Кавычки в значении | Не обязательны для простого слова, но обязательны, если в значении есть пробел или спецсимволы |
| Регистр значения | Важен для class, id, data-*; неважен для перечислимых HTML-атрибутов вроде type - так решает сам HTML |
| [attr=value i] | Специальный флаг i (CSS Selectors Level 4) заставляет сравнивать значение без учёта регистра всегда, для любого атрибута |
Коротко: отвечаем на вопросы
Можно ли объединить несколько условий по атрибуту в одном селекторе?
Да, скобки можно ставить подряд: например, input[type="text"][required] выберет только обязательные текстовые поля - то есть должны совпасть сразу оба условия.
Работает ли [attr=value] для частичного совпадения, например для части текста в href?
Нет, обычный [attr=value] требует полного совпадения. Для частичного совпадения есть отдельные операторы: *= (значение содержит подстроку), ^= (начинается с) и $= (заканчивается на) - про них будет отдельный урок.
Почему [type=Checkbox] сработал для input с type="checkbox", хотя регистр вроде бы другой?
Потому что type - это перечислимый атрибут самого HTML, и HTML сравнивает его значения без учёта регистра. Для своих атрибутов, например data-role, такой поблажки нет - там регистр важен всегда.
Можно ли выбрать элемент, у которого атрибута точно НЕТ?
Да, для этого есть псевдокласс :not() в паре с селектором атрибута: a:not([target]) выберет ссылки без атрибута target. Про :not() будет отдельный урок про псевдоклассы.