- CSS the :not() selector
- What is the :not() selector in CSS?
- :not() rules
- How to use the :not() selector with multiple classes
- Tricks with :first-child, :last-child and :nth-child()
- Conclusion
- CSS-селектор :not. Полезные примеры
- Пример 1. Элемент без класса
- Пример 2. Изменение внешнего вида всех элементов, кроме наведенного
- Пример 3. Меню с разделителями между элементами
- Пример 4. Debug css
- Пример 5. Поля форм
- Поддержка
- Css selector has no class
- Try it
- Syntax
- Description
- Examples
- Using :not() with valid selectors
- HTML
- CSS
- Result
- Using :not() with invalid selectors
- HTML
- CSS
- Result
- Specifications
- Browser compatibility
- See also
- Found a content problem with this page?
- CSS Selector to Select Elements Not Having Certain Class / Attribute / Type
- Notes
CSS the :not() selector
In my previous post
I wrote a bit about the :not() selector and I got a lot feedback that people never heard of this element. So I figured I would dedicate a post just to the :not() CSS selector.
What is the :not() selector in CSS?
The :not() is a CSS pseudo-class that targets elements that do not match the selector given. Since it prevents specific items from being selected, it is known as the negation pseudo-class. In essence you can target anything except what you put in the :not() selector. Lets look at a quick example:
:not() rules
How to use the :not() selector with multiple classes
It is possible to use the :not() selector with multiple classes.
Normally you would just want to do:
But maybe you want to avoid multiple classes? There are no real combinators with :not() and you cannot nest them. But you can chain them, which works similar to and .
p:not(.foo):not(.bar):not(.bold):not(.italic) >
Tricks with :first-child, :last-child and :nth-child()
I use the :not() CSS selector most often with the :first-child or :last-child pseudo-class.
Think of having a list that you want to add some spacing to, but you don’t want to last item to also have spacing at the bottom right? Well with :not() that is super easy to solve!
li:not(:last-child) margin-bottom: 20px; >
You could also do the reverse with :first-child
li:not(:first-child) margin-top: 20px; >
li:not(:nth-child(2)) margin: 20px 0; >
Here is a quick codepen sample to see it in action:
Conclusion
A lot of handy things can be achieved by using the :not() CSS selector. I know I use it a lot of times, for menus, list items and what not. Even flexbox grids!
I hope you learned something from this post, and hopefully you can enhance your CSS skills with this knowledge.
Let me know how you apply the :not() selector, I’m always eager to new learn tricks with it.
CSS-селектор :not. Полезные примеры
В спецификации и блогах про селектор :not обычно приводят какие-то искусственные примеры, которые хоть и объясняют синтаксис и принцип действия, но не несут никакой идеи о том, как получить пользу от нового селектора.
Ну окей, думаю я, в моей практике не встречались такие ситуации. Обходились мы ведь как-то раньше без :not . Приходилось немного переписать структуру селекторов или обнулить пару значений.
Пример 1. Элемент без класса
Селектор :not может быть крайне полезен, когда нам нужно застилить контент сгенерированный пользователем (нет возможности расставить в нем классы), или когда у нас контента очень много и расставлять в нем классы слишком трудоёмко.
Например, мы хотим на сайте сделать красивые буллиты для ненумерованных списков ul li . Мы пишем код:
ul li < /* наши красивые стили */ >
В результате, наши красивые буллиты появляются не только в контенте, но и, например, в навигации, где тоже используются ul li .
Мы ограничиваем область действия селектора:
Навигацию мы спасли, но ненужные буллиты всё еще вылазят на слайдерах, списках новостей и других конструкциях внутри .content , где тоже используются ul li .
1) обнулить мешающие стили в слайдерах и других местах. Но это противоречит « DRY » и является одним из признаков «вонючего» кода. К тому же не решает проблему раз и навсегда: добавите, например, аккордеон и списки в нем снова придется обнулять.
2) пойти от обратного и ставить класс всем спискам, которые нужно стилизовать:
Это добавляет лишней работы по расстановке классов в контенте. Иногда имеет смысл, но лишнюю работу никто не любит.
3) стилизовать только те ul li , у которых нет никаких классов вообще:
Победа! Нам не нужно делать дополнительную работу по расстановке классов в контенте. А на слайдерах, аккордеонах и прочих конструкциях, которые не должны выглядеть как списки, но используют их в своей разметке, в 99% случаев уже будут свои классы, и наши стили их не затронут.
Этот прием — «выбирать только элементы без класса» — очень полезен для оформления пользовательского контента и его можно применять не только к спискам, но и для других случаев.
Пример 2. Изменение внешнего вида всех элементов, кроме наведенного
Такой эффект можно реализовать без :not путем перезаписи значений. И это будет работать в бо́льшем количестве браузеров.
/* с перезаписью свойств */ ul:hover li < opacity:0.5; > ul:hover li:hover < opacity:1; >
Но если придется обнулять слишком много свойств, то есть смысл использовать :not .
/* используя :not() */ ul:hover li:not(:hover) < opacity:0.5; >
Пример 3. Меню с разделителями между элементами
Как и в предыдущем примере, желаемого можно добиться несколькими способами.
Через перезапись свойств. Но тут два правила вместо одного, что не есть « DRY ».
.menu-item:after < content: ' | '; > .menu-item:last-child:after < content: none; >
Через :nth-last-child() . Одно правило, но тяжело читается.
.menu-item:nth-last-child(n+2):after < content: ' | '; >
Через :not() — самая короткая и понятная запись.
.menu-item:not(:last-child):after < content: ' | '; >
Пример 4. Debug css
Удобно для отладки и самоконтроля искать/подсвечивать картинки без alt, label без for и другие ошибки.
/* подсвечиваем теги без необходимых атрибутов */ img:not([alt]), label:not([for]), input[type=submit]:not([value]) < outline:2px solid red; > /* тревога, если первый child внутри списка не li и прочие похожие примеры */ ul > *:not(li), ol > *:not(li), dl > *:not(dt):not(dd) < outline:2px solid red; >
Пример 5. Поля форм
Раньше текстовых полей форм было не много. Достаточно было написать:
select, textarea, [type="text"], [type="password"] < /* стили для текстовых полей ввода */ >
С появлением новых типов полей в HTML5 этот список увеличился:
select, textarea, [type="text"], [type="password"], [type="color"], [type="date"], [type="datetime"], [type="datetime-local"], [type="email"], [type="number"], [type="search"], [type="tel"], [type="time"], [type="url"], [type="month"], [type="week"] < /* стили для текстовых полей ввода */ >
Вместо перечисления 14 типов инпутов можно исключить 8 из них:
select, textarea, [type]:not([type="checkbox"]):not([type="radio"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="range"]):not([type="file"]):not([type="image"]) < /* стили для текстовых полей ввода */ >
Ладно, этот пример не очень красив, и я рекомендую всё же первый вариант с перечислением, он работает с IE8+, а второй вариант с IE9+.
Поддержка
Следует заметить, что согласно спецификации в скобках селектора :not() может стоять только простой селектор и в скобках нельзя использовать сам селектор :not() . Если нужно исключить несколько элементов, :not() можно повторить несолько раз, как в примере 5.
Если очень нужны CSS3-селекторы в браузерах, которые их не поддерживают, можно использовать полифил selectivizr.
Css selector has no class
The :not() CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class.
Try it
The :not() pseudo-class has a number of quirks, tricks, and unexpected results that you should be aware of before using it.
Syntax
The :not() pseudo-class requires a comma-separated list of one or more selectors as its argument. The list must not contain another negation selector or a pseudo-element.
Description
There are several unusual effects and outcomes when using :not() that you should keep in mind when using it:
- Useless selectors can be written using this pseudo-class. For example, :not(*) matches any element which is not an element, which is obviously nonsense, so the accompanying rule will never be applied.
- This pseudo-class can increase the specificity of a rule. For example, #foo:not(#bar) will match the same element as the simpler #foo , but has the higher specificity of two id selectors.
- The specificity of the :not() pseudo-class is replaced by the specificity of the most specific selector in its comma-separated argument of selectors; providing the same specificity as if it had been written :not(:is(argument)) .
- :not(.foo) will match anything that isn’t .foo , including and .
- This selector will match everything that is «not an X». This may be surprising when used with descendant combinators, since there are multiple paths to select a target element. For instance, body :not(table) a will still apply to links inside a , since , , , , , etc. can all match the :not(table) part of the selector.
- You can negate several selectors at the same time. Example: :not(.foo, .bar) is equivalent to :not(.foo):not(.bar) .
- If any selector passed to the :not() pseudo-class is invalid or not supported by the browser, the whole rule will be invalidated. The effective way to overcome this behavior is to use :is() pseudo-class, which accepts a forgiving selector list. For example :not(.foo, :invalid-pseudo-class) will invalidate a whole rule, but :not(:is(.foo, :invalid-pseudo-class)) will match any (including and ) element that isn’t .foo .
Examples
Using :not() with valid selectors
This example shows some simple cases of using :not() .
HTML
p>I am a paragraph.p> p class="fancy">I am so very fancy!p> div>I am NOT a paragraph.div> h2> span class="foo">foo inside h2span> span class="bar">bar inside h2span> h2>
CSS
.fancy text-shadow: 2px 2px 3px gold; > /* elements that don't have a class `.fancy` */
p:not(.fancy) color: green; > /* Elements that are not elements */
body :not(p) text-decoration: underline; > /* Elements that are not s or `.fancy` */ body :not(div):not(.fancy) font-weight: bold; > /* Elements that are not s or `.fancy` */ body :not(div, .fancy) text-decoration: overline underline; > /* Elements inside an that aren't a with a class of `.foo` */ h2 :not(span.foo) color: red; >
Result
Using :not() with invalid selectors
This example shows the use of :not() with invalid selectors and how to prevent invalidation.
HTML
p class="foo">I am a paragraph with .foop> p class="bar">I am a paragraph with .barp> div>I am a div without a classdiv> div class="foo">I am a div with .foodiv> div class="bar">I am a div with .bardiv> div class="foo bar">I am a div with .foo and .bardiv>
CSS
/* Invalid rule, does nothing */ p:not(.foo, :invalid-pseudo-class) color: red; font-style: italic; > /* Select allelements without the `foo` class */
p:not(:is(.foo, :invalid-pseudo-class)) color: green; border-top: dotted thin currentcolor; > /* Select all elements without the `foo` or the `bar` class */ div:not(.foo, .bar) color: red; font-style: italic; > /* Select all elements without the `foo` or the `bar` class */ div:not(:is(.foo, .bar)) border-bottom: dotted thin currentcolor; >
Result
The p:not(.foo, :invalid-pseudo-class) rule is invalid because it contains an invalid selector. The :is() pseudo-class accepts a forgiving selector list, so the :is(.foo, :invalid-pseudo-class) rule is valid and equivalent to :is(.foo) . Thus, the p:not(:is(.foo, :invalid-pseudo-class)) rule is valid and equivalent to p:not(.foo) .
If :invalid-pseudo-class was a valid selector, the first two rules above would still be equivalent (the last two rules showcase that). The use of :is() makes the rule more robust.
Specifications
Browser compatibility
BCD tables only load in the browser
See also
Found a content problem with this page?
This page was last modified on Jul 18, 2023 by MDN contributors.
Your blueprint for a better internet.
CSS Selector to Select Elements Not Having Certain Class / Attribute / Type
The :not CSS pseudo-class can be used to select elements that do not contain a specific class, id, attribute etc.
Usually we need to select elements that satisfy a certain condition — they may have a certain class / attribute / id etc.
/* select all elements having class "menu-active" */ .menu-active < font-weight: 700; >/* select all "p" elements */ p < line-height: 2; >/* select input elements having "text" type attribute */ input[type="text"]
However many times we need just the opposite case — it may be required to select elements that are not having a specific class / attribute / id etc.
This can be achieved using the :not pseudo-class selector.
:not has a functional notation and takes a simple selector as its argument.
/* select all elements not having class "menu-active" */ :not(.menu-active) < font-weight: 300; >/* select "p" elements not having class "menu-active" */ p:not(.menu-active) < font-weight: 300; >/* select all elements except "p" */ :not(p) < line-height: normal; >/* select input elements not having "text" type attribute */ input:not([type="text"])
Notes
Currently :not takes only a simple selector as its argument. No complex selectors are allowed.
There are proposals to bring complex selectors as argument to :not . However most browsers have not implemented it yet.