Школа
Веб-разработка

Псевдокласс :not

7 апр 2022
👁 3173   🗩2
Веб-разработка

Псевдокласс :not

7 апр 2022
👁 3173   🗩2
Игорь Петров
Разработчик, преподаватель Школы бюро
Полезно
 7
7
Непонятно
  
Войдите в Бюросферу, чтобы голосовать

Сегодня короткий совет о моём любимом псевдоклассе :not.

Обычно в ЦСС применяют стили к элементу, который соответствует какому‑то условию: является определённым тегом, имеет нужный класс, находится первым, последним и так далее.

Псевдокласс :not применяет стили к элементу, который не соответствует условию: не является определённым тегом, не обладает классом, не стоит первым. Иногда этот псевдокласс помогает сделать код сильно проще и нагляднее.

Классический пример: обычно ненужные отступы последних элементов убирают в два шага. Сначала задают отступы для всех модулей, а затем обнуляют для последнего их них. Используя :not можно написать короче и нагляднее: не извращаться, а прямо сказать браузеру — «добавь отступ всем непоследним элементам».

Было
ul li { margin-bottom: 9px; }
                      
ul li:last-child { margin-bottom: 0; }
Стало
ul li:not(:last-child) { margin-bottom: 9px; }

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

.article:not(.is__loaded) { … }
                        
input:not(:valid) { … }
                        
.spread:not(.is__service) { … }
                        
.product:not(.is__accessory) .suggestions { … }

Ещё :not часто выручает, когда приходится парсить разметку Яваскриптом и нужно отфильтровать лишнюю шелуху:

// Заголовки, которые не нужно учитывать
const IGNORED_HEADERS = [
  '.sectionTitle-header h1',
  '.is__noHeader',
  '.isNoHeader',
  '.is__noHeader h2',
  '.isNoHeader h2',
]
                        
// Превращаем джойном массив заголовков в строку через запятую и передаём в :not
const $spreadTitle = $spread.querySelectorAll(`h2:not(${IGNORED_HEADERS.join(',')})`)
          
// А в Джейквери есть удобный чейнинг-метод not(), который умеет принимать массив
const $spreadTitle = $spread.find('h2').not(IGNORED_HEADERS)

P. S. Вложить один :not в другой не получится, зато можно сделать забавный в своей бессмысленности селектор :not(*), который найдёт любой элемент, являющийся не любым, то есть не найдёт ничего :‑)

P. P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Веб‑разработка
Полезно
 7
7
Непонятно
  
Войдите в Бюросферу, чтобы голосовать
Отправить
Поделиться
Поделиться
Запинить
Твитнуть

Комментарии

Иван Бойко

Всем привет.
:not(<селектор>,<селектор>,<селектор> ) работает только в спецификации ЦСС селекторов уровня 4.

Для поддержки более старых версий браузеров используют конструкцию: :not(<селектор>):not(<селектор>):not(<селектор>). Работает как условное AND

Игорь Петров

Иван, хорошее дополнение! А для решения такой задачи в более‑менее современных браузерах можно комбинировать :not с :is, например:
p:not(:is(.lead, .highlighted)) { … }

Цель рубрики — обсуждение вопросов дизайна, веб-разработки, переговоров, редактуры и управления.
Комментарии модерируются. Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры.

Рекомендуем другие советы