:not

Отрицаем всё! Исключаем из выборки селектора элементы с определённым признаком.

Время чтения: меньше 5 мин

Кратко

Скопировано

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

Пример

Скопировано

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

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

Задаём нижние отступы всем пунктам списка:

        
          
          li {  margin-bottom: 1em;}
          li {
  margin-bottom: 1em;
}

        
        
          
        
      

Сбрасываем нижний отступ у последнего пункта списка, чтобы не висел:

        
          
          li:last-child {  margin-bottom: 0;}
          li:last-child {
  margin-bottom: 0;
}

        
        
          
        
      

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

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

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

        
        
          
        
      

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

Как пишется

Скопировано

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

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

Как понять

Скопировано

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

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

Подсказки

Скопировано

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

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

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

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

Красим в красный все пункты списка, кроме последнего элемента и кроме тех, у которых есть класс .active:

        
          
          li:not(:last-child):not(.active) {  color: red;}
          li:not(:last-child):not(.active) {
  color: red;
}

        
        
          
        
      

На практике

Скопировано

Алёна Батицкая советует

Скопировано

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

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