- 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. Поля форм
- Поддержка
- How to exclude particular class name in CSS selector?
- 3 Answers 3
- Method 1
- Method 2
- Method 3
- Is there a CSS selector for element without any class?
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.
How to exclude particular class name in CSS selector?
I’m trying to apply background-color when a user mouse hover the element whose class name is «reMode_hover» . But I do not want to change color if the element also has «reMode_selected» Note: I can only use CSS not javascript because I’m working within some sort of limited environment. To clarify, my goal is to color the first element on hover but not the second element. HTML
I tried below hoping the first definition would work but it is not. What am I doing wrong? CSS
/* do not apply background-color so leave this empty */ .reMode_selected .reMode_hover:hover < >.reMode_hover:hover
3 Answers 3
One way is to use the multiple class selector (no space as that is the descendant selector):
.reMode_hover:not(.reMode_selected):hover
shouldn’t it be: .reMode_hover:not(‘.reMode_selected’):hover In my experience those quotes are necessary.
@MakanTayebi You raise an excellent point regarding quotes around the selector. TL;DR: It is indeed best to use them. Thorough explanation at stackoverflow.com/a/5578880/1772379 .
Is that still the case? Haven’t tried this in other browsers, but in the latest version of Firefox that I’m working in, the :not selector only worked when I removed the quotes.
In modern browsers you can do:
.reMode_hover:not(.reMode_selected):hover<>
Consult http://caniuse.com/css-sel3 for compatibility information.
Method 1
The problem with your code is that you are selecting the .remode_hover that is a descendant of .remode_selected . So the first part of getting your code to work correctly is by removing that space
.reMode_selected.reMode_hover:hover
Then, in order to get the style to not work, you have to override the style set by the :hover . In other words, you need to counter the background-color property. So the final code will be
.reMode_selected.reMode_hover:hover < background-color:inherit; >.reMode_hover:hover
Method 2
An alternative method would be to use :not() , as stated by others. This will return any element that doesn’t have the class or property stated inside the parenthesis. In this case, you would put .remode_selected in there. This will target all elements that don’t have a class of .remode_selected
However, I would not recommend this method, because of the fact that it was introduced in CSS3, so browser support is not ideal.
Method 3
A third method would be to use jQuery. You can target the .not() selector, which would be similar to using :not() in CSS, but with much better browser support
Is there a CSS selector for element without any class?
but this is not what I want, because it is not very manageable once the styles get complex and in some cases it is hard to do the «reset» properly (of course not in this simplified example).
thanks for editing the question. I mentioned sass because I am happy enough even with sass only solution. Pure css would be better however.
This has absolutely nothing to do with Sass because whatever selector you write must be valid CSS in the end. The tag was removed for a reason. Do not add it back in.
Your idea somehwat goes against the ideas of inheritance and specificity in CSS. Instead of considering the styling of .special as a «reset», you should see it as a «refinement» applied to a subset of your section selection. The solutions given to your question won’t give you optimal performance and will make things more complicated. (By the way, your first CSS example looks shorter because you omit : section < color: black; >).
@Nicolas Le Thierry d’Ennequin: The reason section < color: black; >is omitted is because it’s not needed in the first place — presumably it’s taking on the default already. The second example clearly shows the redundancy of setting a color for all sections and then having to remove it from every possible class that the sections can have. I don’t understand why you think the first example would be more complicated. As for performance, between that and maintainability, you only get to pick one.