Псевдокласс :not() – один из самых удобных инструментов CSS для «вычитания» элементов из выборки: вместо того чтобы перечислять, к чему применить стиль, вы описываете, к чему его применять не нужно. Раньше это была скромная возможность, но к 2026 году :not() умеет принимать целые списки селекторов, отлично работает в связке с :has() и поддерживается всеми актуальными браузерами.
Как работает :not()
Псевдокласс :not(X) принимает селектор-аргумент и исключает из выборки всё, что этому селектору соответствует. Селектор p:not(.intro) выбирает каждый абзац, у которого нет класса intro: сначала указывается основной элемент (p), затем следует псевдокласс отрицания :not(), а внутри скобок – тот селектор, который нужно исключить.
/* Все абзацы, кроме вводного */
p:not(.intro) {
color: #555;
}
Списки селекторов внутри :not() (2026)
Главное изменение последних лет – :not() принимает список селекторов через запятую. Это часть спецификации Selectors Level 4, и такой синтаксис поддерживается во всех современных браузерах.
/* Пункты меню без модификаторов is-active и is-disabled */
.menu__item:not(.is-active, .is-disabled) {
cursor: pointer;
}
Раньше приходилось писать цепочку из нескольких псевдоклассов – .menu__item:not(.is-active):not(.is-disabled). Обе записи по-прежнему рабочие, но список короче и читаемее. Для поддержки очень старых браузеров используйте именно цепочку.
Специфичность :not()
Сам псевдокласс :not() не добавляет специфичности, но его аргумент – добавляет. Вес правила равен специфичности самого «тяжёлого» селектора внутри скобок. Это частый источник неожиданно «сильных» правил: :not(#id) получает специфичность идентификатора. Держите аргументы простыми, если хотите предсказуемый каскад.
Связка с :has() и :nth-child of S
В 2026 году :not() редко используют в одиночку. Он хорошо комбинируется с другими псевдоклассами Selectors Level 4:
/* Карточки товара, у которых НЕТ вложенного бейджа «нет в наличии» */
.card:not(:has(.badge--out)) {
border-color: #0a0;
}
/* Первые три видимых пункта: :nth-child принимает фильтр of S */
li:nth-child(-n+3 of :not(.hidden)) {
font-weight: 700;
}
Про выбор первых элементов подробнее – в гайде «Выбрать первые три элемента из списка с помощью CSS».
Частые ошибки
- Пустой аргумент.
:not()без селектора внутри недопустим и обрушит всё правило. - Список – это логика «хотя бы одно». В записи
:not(.a, .b)элемент исключается, если совпал хотя бы с одним селектором. Цепочка:not(.a):not(.b)отсекает по очереди: для простых классов итог тот же, но для сложных селекторов поведение отличается. - Забытая специфичность. Правило с
:not()может неожиданно перебить другие стили – см. раздел выше.
Поддержка браузеров и производительность
Простой :not(.class) поддерживается всеми браузерами уже более десяти лет. Возможность передавать список селекторов и сложные селекторы – часть Selectors Level 4 и доступна во всех актуальных версиях Chrome, Edge, Firefox и Safari; для устаревших браузеров применяйте цепочку из нескольких :not(). Точную таблицу совместимости всегда стоит сверять на caniuse.com.
По производительности :not() – быстрый селектор, но избегайте чрезмерно широких выборок вроде *:not(...) на больших деревьях: браузер проверит каждый узел документа. Держите слева от псевдокласса конкретный элемент или класс.
Эти же приёмы фильтрации пригодятся при вёрстке навигации – например, в новом шаблоне постраничной навигации или при оформлении вкладок (tabs).