skip to main content

:not

css

Кратко 🔗

Супер-полезный псевдокласс, который поможет вам неплохо так сэкономить строчки кода. Суть работы этого парня — отсечь все элементы, не подходящие под условие. Звучит сложнее, чем выглядит.

Пример 🔗

Как вы наверняка уже знаете, между элементами принято задавать отступы так, чтобы у последнего / первого не было лишних отступов, чтобы они не торчали без дела и не меняли размеры родителя без причины.

Например, есть задача задать нижний отступ всем пунктам списка, кроме последнего:

/* Задаём нижние отступы всем пунктам списка */
li {
margin-bottom: 1em;
}

/* Сбрасываем нижний отступ у последнего пункта списка, чтобы не висел */
li:last-child {
margin-bottom: 0;
}

Для самого простого решения этой задачи нам потребовалось 2 блока кода. Но, скорее всего, в вашем проекте нужно будет сбросить лишние отступы не только для этого элемента. Точно можно как-то проще.

Конечно можно! Сократим два блока кода до одного, используя нашего маленького помощника — псевдокласс :not. Выберем все пункты списка кроме последнего и зададим им нижние отступы:

li:not(:last-child) {
margin-bottom: 1em;
}

Вуа-ля! Красиво, аккуратно, а главное работает ровно как задумывалось 😏

Как пишется 🔗

Берём любой селектор, ставим двоеточие и пишем ключевое слово not. После него ставим круглые скобки и внутри них указываем ещё один селектор, который должен быть исключён из выборки. Селектор в скобках может быть любым: по тегу, по классу, по идентификатору, псевдокласс, селектор по атрибуту или универсальный селектор *. Одно ограничение: нельзя использовать в качестве аргумента псевдоэлементы (:before, :after и другие).

Важно помнить, что внутри скобок не может быть составного селектора!

Например, вот такая конструкция не сработает вообще: a:not(.link a) 😞

Ещё можно выбирать внутри body любой элемент, не являющийся, например, абзацем: body :not(p). По аналогии можете выбирать любой элемент внутри определённого родителя, но не подходящий под условие.

Как это понять 🔗

Можно сказать заумно, что :not(Х) это функция, которая принимает в качестве аргумента селектор Х и находит в разметке элементы, не соответствующие этому самому элементу Х.

А можно проще: мы командуем браузеру «Выбери все элементы подходящие к селектору до :not и исключи из выборки все элементы, подходящие под селектор в круглых скобках».

Подсказки 🔗

💡 Слева от :not не обязательно должен быть селектор. Может написать :not(.hidden) и браузер выберет вообще все элементы на странице, кроме тех, у которых есть класс .hidden.

💡 Псевдокласс :not повышает специфичность селектора на 10 пунктов. Читайте подробнее про специфичность.

💡 Если очень захотеть — можно в космос полететь написать бесполезный селектор: :not(*). Такой селектор выберет любой элемент, который не является любым элементом 🤦‍♀️

💡 Нельзя вкладывать один :not в другой.

💡 Можно выстраивать цепочки из :not. Тогда выборка будет уменьшаться по порядку исключая элементы, подходящие под условия:

/* Красим в красный все пункты списка, кроме последнего элемента
и кроме тех, у которых есть класс _active */

li:not(:lact-child):not(._active) {
color: red;
}

В работе 🔗

🛠 После того, как поддержка этого псевдокласса была внедрена во все браузеры я стала использовать его повсеместно. Гораздо удобнее написать один селектор, чем два блока кода для такой тривиальной задачи, как сброс последнего отступа или выбор элемента за исключением какого-то класса.

Из последнего: мне нужно было стилизовать все поля ввода, кроме тех, что были скрыты (иногда в форму добавляют скрытые поля, чтобы отправить вместе с данными пользователя служебные данные). Вместо того, чтобы писать составной селектор, выбирая отдельные поля или выдумывать отдельный класс только для тех полей, которые видны / не видны, я написала селектор input:not([hiddent="true"]) и интерпретатор применил нужные мне стили только тем инпутам, у которых нет атрибута hidden.

Автор: Алёна,