CSS - :not()
Псевдокласс :not() в CSS представляет собой функциональный селектор для точечного исключения элементов из стилизации. Он помогает писать более чистый и лаконичный CSS, избегая лишних переопределений.Подробнее о псевдоклассе :not()
Псевдокласс :not() в CSS используется для выбора элементов, которые не соответствуют указанному селектору. Это позволяет применять стили к элементам, исключая те, которые соответствуют определённому критерию.
:not() - это универсальный и простой способ гибко управлять логикой применения стилей, исключая из набора выборки ненужные элементы без дополнительных классов или изменений HTML. Это делает CSS выразительнее и избавляет от избыточных обёрток или кодовых усложнений.
Псевдокласс :not() может быть очень полезен для создания более специфичных и гибких селекторов, что позволяет более точно управлять стилями на веб-странице.
Вы можете вкладывать псевдокласс :not() внутрь других селекторов, создавая более сложные конструкции. Псевдокласс :not() сам по себе является частью общего селектора, и его можно свободно комбинировать с любыми другими селекторами, включая обычные теги, классы, атрибуты и даже другие псевдоэлементы.
Поддержка браузеров псевдокласса :not()
Браузер | Поддержка | Версия+ | Примечания |
---|---|---|---|
Chrome | Да | 88+ | Полная поддержка с 19.01.2021 |
Да | 105+ | С января 2021 года | |
Firefox | Да | 84+ | Поддержка с 15 декабря 2020 |
Edge | Да | 88+ | Поддержка с 21.01.2021 |
Safari | Да | 9+ | Поддержка с 30.09.2015 |
Internet Explorer | Нет | - | Не поддерживается |
Opera | Да | 74+ | Поддержка с 02.02.2021 |
iOS Safari | Да | 9+ | Поддержка с 16 сентября 2015 |
Android Browser | Да | 88+ | Поддержка с 19.01.2021 |
Примеры синтаксиса :not()
Основной синтаксис :not()
element:not(selector) { правила стиля }
/* Так нельзя - внутри :not() только простые селекторы */
div:not(.class1 + .class2) { правила стиля }
Использование :not() с комбинаторами
Пробел (потомки)
Выбираем все <p>
внутри <div>
, кроме тех, у которых класс .ignore
.
div p:not(.ignore) {
color: red;
}
<div>
<p>Стиль будет</p>
<p class="ignore">Нет стиля</p>
<span><p>Стиль будет (вложенный)</p></span>
</div>
Дочерний комбинатор (>
)
Выбираем только прямых детей <div>
, кроме .skip
.
div > :not(.skip) {
border: 1px solid blue;
}
<div>
<p>Стиль есть (ребёнок)</p>
<span class="skip">Нет стиля</span>
<ul>
<li>Нет стиля (внук)</li>
</ul>
</div>
Соседний комбинатор (+
)
Стилизуем параграф, который идёт после <h2>
, но только если он не .no-style
.
h2 + p:not(.no-style) {
font-weight: bold;
}
<h2>Заголовок</h2>
<p>Стиль будет</p>
<p class="no-style">Нет стиля</p>
Общий комбинатор следующих элементов (~
)
Выделяем все <li>
после .start
, кроме .special
.
.start ~ li:not(.special) {
color: green;
}
<ul>
<li>Обычный</li>
<li class="start">Старт</li>
<li>Стиль есть</li>
<li class="special">Нет стиля</li>
<li>Стиль есть</li>
</ul>
Использование :not() с другими псевдоклассами
:not
+ :hover
Изменяем цвет кнопок при наведении, кроме .disabled
.
button:not(.disabled):hover {
background: gold;
}
<button>Наведи меня</button>
<button class="disabled">Не реагирует</button>
:not()
+ :nth-child()
Стилизуем каждую чётную строку таблицы, кроме .header
.
tr:not(.header):nth-child(even) {
background: #f0f0f0;
}
<table>
<tr class="header"><td>Заголовок</td></tr>
<tr><td>Строка 1</td></tr>
<tr><td>Строка 2 (стиль)</td></tr>
<tr><td>Строка 3</td></tr>
</table>
Использование :not() с атрибутами
Операторы для работы с атрибутами: ^=
- начинается с, $=
- заканчивается на, *=
- содержит подстроку.
Исключение полей формы по атрибуту type
Стилизуем все <input>
, кроме type="checkbox"
и type="submit"
.
input:not([type="checkbox"], [type="submit"]) {
border: 2px solid #3498db;
padding: 8px;
width: 200px;
}
<input type="text" placeholder="Текст">
<input type="checkbox"> Чекбокс (без стиля)
<input type="submit" value="Отправить">
<input type="password" placeholder="Пароль">
Исключение ссылок с определённым href
Сделаем все ссылки зелёными, кроме тех, что ведут на https://example.com
.
a:not([href="https://example.com"]) {
color: #2ecc71;
text-decoration: underline;
}
<a href="https://google.com">Google</a>
<a href="https://example.com">Example (без стиля)</a>
<a href="/about">Локальная ссылка</a>
Исключение элементов с пустым атрибутом
Скрываем все изображения без alt
.
img:not([alt]) {
display: none;
}
<img src="cat.jpg" alt="Кот">
<img src="dog.jpg" alt="">
<img src="bird.jpg"> <!-- Будет скрыто -->
Селектор :not([alt])
выберет элементы без атрибута alt
вообще или с пустым значением alt=""
.
Исключение по частичному совпадению атрибута
Выделяем все ссылки, у которых href
не начинается с #
.
a:not([href^="#"]) {
border-left: 3px solid #e74c3c;
padding-left: 10px;
}
<a href="#top">Якорь (без стиля)</a>
<a href="https://site.com">Внешняя ссылка</a>
<a href="/page">Внутренняя ссылка</a>
Комбинация атрибутов и классов
Стилизуем все текстовые поля type="text"
, кроме тех, у которых есть класс .readonly
.
input[type="text"]:not(.readonly) {
background: #f9f9f9;
border-color: #bdc3c7;
}
<input type="text" placeholder="Можно редактировать">
<input type="text" class="readonly" placeholder="Только чтение">
<input type="email" placeholder="Email">
Исключение по data
атрибутам
Скрываем все элементы с data-hidden="true"
.
div:not([data-hidden="true"]) {
display: block;
}
<div data-hidden="true">Скрыто</div>
<div>Видимо</div>
<div data-hidden="false">Тоже видимо</div>
Сложный пример использования
Устанавливаем стиль для всех input
, кроме checkbox
, radio
и disabled
.
input:not([type="checkbox"], [type="radio"], :disabled) {
border: 1px solid green;
}
<!-- Будут с стилем -->
<input type="text" placeholder="Текстовое поле">
<input type="email" placeholder="Email">
<input type="password" placeholder="Пароль">
<!-- Без стиля (исключены) -->
<input type="checkbox"> Чекбокс<br>
<input type="radio"> Радио-кнопка<br>
<input type="text" disabled placeholder="Отключенное поле">
Ограничения :not()
Нельзя вкладывать :not() в :not()
/* Так не работает! */
div:not(:not(.test)) { правила стиля }
Допускаются только простые селекторы внутри
/* Так не работает! */
div:not(.a.b) { правила стиля }
Отказоустойчивость
Если в :not()
передан невалидный селектор, браузер проигнорирует только его, но применит правило к остальным допустимым селекторам.
/* Если :invalid-pseudo не существует, браузер проигнорирует только его */
button:not(:disabled, :invalid-pseudo) {
background: green;
}
Поддержка сложных селекторов
Тип селектора | Пример | Поддержка | Альтернатива |
---|---|---|---|
Простые через запятую | :not(.a, .b) |
Chrome/Firefox/Edge 88+ | :not(.a):not(.b) |
Вложенный :is() |
:not(:is(.a, .b)) |
Chrome/Firefox/Edge 88+ | - |
Составной селектор | :not(.a.b) |
Нигде | JavaScript |
Комбинаторы (>, +, ~) | :not(div > span) |
Нигде | :not(div) :not(span) |
Псевдоклассы | :not(:hover, :focus) |
Chrome/Firefox/Edge 88+ | :not(:hover):not(:focus) |
Атрибуты | :not([type="text"], [disabled]) |
Chrome/Firefox/Edge 88+ | :not([type="text"]):not([disabled]) |
Для максимальной совместимости со старыми браузерами (особенно IE11) рекомендуется использовать цепочку :not()
вместо перечисления через запятую.
Оптимизация работы :not()
Браузер обрабатывает :not()
справа налево, и производительность зависит от сложности селекторов внутри него, а не от глубины вложенности.
Ставьте простые селекторы внутри :not()
/* Плохо */
div:not(div > span .class)
/* Хорошо */
div:not(.unwanted-class)
Используйте перечисление через запятую (вместо цепочки):
/* Оптимально (Chrome/Firefox) */
a:not([href^="#"], [href^="javascript:"])
Избегайте избыточных проверок
/* Избыточно */
div:not(:not(p))
/* Эквивалентно */
div:not(p)
Специфичность селектора внутри :not()
/* Медленнее (высокая специфичность) */
div:not(#someId .class[data-attr])
/* Быстрее (низкая специфичность) */
div:not(.simple-class)
Демо примеры использования :not()
Все предоставленные демо примеры можно редактировать прямо в редакторе, протестируйте свои знания на готовых примерах использования псевдокласса :not()
.
Выделение ссылок
Делаем все ссылки красными, кроме первой.
Изменение фона списков
Меняем фон у всех списков, кроме .main-list
.
Выборка полей ввода
Выделяем все поля ввода, кроме пароля.
Оформления у кнопок
Оформляем все кнопки, кроме последней.
Исключение нескольких типов одновременно
Добавляем рамку ко всем полям, кроме чекбоксов и радиобатонов.
Совместимость с атрибутами и селектором смежных элементов
Устанавливаем рамку вокруг изображений, кроме первого.
Комбинация с псевдоклассами и псевдоэлементами.
Показываем сообщение до начала каждой строки списка, кроме первой.
Динамическое изменение дизайна форм
Обводим рамки вокруг всех полей ввода, кроме полей с типом "submit"
.
Настройка внешнего вида интерактивных элементов
Кнопки становятся красными, если не активированы :active
.
Применение вместе с другими селекторами
Для любых полей формы (кроме radio
и checkbox
), если форма имеет класс active
, добавляем рамку справа.
Сложный пример использования :not()
Комбинирование нескольких :not()
для точного таргетинга элементов.