: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. После него ставим круглые скобки и внутри них указываем ещё один селектор, который должен быть исключён из выборки. Селектор в скобках может быть любым, главное чтобы он не включал псевдоэлементы.

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

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

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

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

Секция статьи "Как это понять"

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

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

Подсказки

Секция статьи "Подсказки"

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

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

💡 Если очень захотеть — можно в космос полететь написать бесполезный селектор: :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.