Могу ли я написать селектор CSS, выбирающий элементы, НЕ имеющие определенного класса или атрибута?

647

Я хотел бы написать правило селектора CSS, которое выбирает все элементы, которые не имеют определенного класса. Например, с учетом следующего HTML:

<html class="printable">
    <body class="printable">
        <h1 class="printable">Example</h1>
        <nav>
            <!-- Some menu links... -->
        </nav>
        <a href="javascript:void(0)" onclick="javascript:self.print()">Print me!</a>
        <p class="printable">
            This page is super interresting and you should print it!
        </p>
    </body>
</html>

Я хотел бы написать селектор, который выбирает все элементы, которые не имеют «printable» класса, в данном случае это nav и a элементы.

Это возможно?

ПРИМЕЧАНИЕ: в реальном HTML, где я хотел бы использовать это, будет гораздо больше элементов, у которых нет класса «пригодный для печати», чем у меня (я понимаю, что в приведенном выше примере все наоборот).

Дэвид Нордвалл
источник

Ответы:

901

Обычно вы добавляете селектор класса в :not()псевдокласс следующим образом:

:not(.printable) {
    /* Styles */
}

:not([attribute]) {
    /* Styles */
}

Но если вам нужна лучшая поддержка браузера (IE8 и старше не поддерживает :not()), вы , вероятно , лучше создавать правила стилей для элементов , которые делают имеют «печать» класс. Если даже это неосуществимо, несмотря на то, что вы говорите о фактической наценке, вам, возможно, придется обойтись без этого ограничения.

Имейте в виду , что в зависимости от свойств вы настраиваете в этом правиле, некоторые из них могут быть либо наследуется потомками , которые являются .printable или иным образом повлиять на их так или иначе. Например, хотя displayон и не наследуется, установка параметра display: nonea :not(.printable)не позволит отображать его и всех его потомков, поскольку он полностью удаляет элемент и его поддерево из макета. Вы можете часто обойти это, используя visibility: hiddenвместо этого, что позволит отображать видимых потомков, но скрытые элементы будут по-прежнему влиять на макет, как они изначально делали. Короче, просто будь осторожен.

BoltClock
источник
4
Как небольшой кусочек информации, поддержка браузером не зависящих от медиа аспектов CSS часто одинакова для разных типов медиа - если браузер не поддерживает :not()на экране, он не будет поддерживать его и в печати.
BoltClock
19
Обратите внимание, что :not()требуется только простой селектор, что означает, что он не может содержать вложенные селекторы, такие как :not(div .printable)- см. Синтаксис селектора W3C
Стив Эйнон,
1
Я просто попробовал это для .active a: not (.active a) не работал для меня. Но: не (.active) сделал!
user2367418
Когда вы говорите, что это не работает для вас, вы, вероятно, имеете в виду, что это не работает для вас , верно? Это не значит, что это не работает, это, вероятно, случай специфичности - свойства в вашем :not(.active)правиле могли быть просто переопределены свойствами в правиле с более высоким приоритетом.
атп
1
@Kilves: Вы уверены в этом? Специфика :not()аргумента его аргумента, а значит :not(div), одинаково специфична для div, :not(.cls)для .clsи :not(#id)для #id.
BoltClock
180
:not([class])

Фактически, это выберет все, к чему не применяется класс css ( class="css-selector").

Я сделал демо jsfiddle

    h2 {color:#fff}
    :not([class]) {color:red;background-color:blue}
    .fake-class {color:green}
    <h2 class="fake-class">fake-class will be green</h2>
    <h2 class="">empty class SHOULD be white</h2>
    <h2>no class should be red</h2>
    <h2 class="fake-clas2s">fake-class2 SHOULD be white</h2>
    <h2 class="">empty class2 SHOULD be white</h2>
    <h2>no class2 SHOULD be red</h2>

Это поддерживается? Да: Caniuse.com (по состоянию на 02 января 2020 г.) :

  • Поддержка: 98,74%
  • Частичная поддержка: 0,1%
  • Итого: 98,84%

Забавно редактировать, я гуглил по противоположности: нет. CSS отрицание?

selector[class]  /* the oposite of :not[]*/
Мильче Патерн
источник
109

:notКласса Отрицание псевдо

Псевдокласс CSS отрицания :not(X), является функциональной нотацией, принимающей простой селектор X в качестве аргумента. Он соответствует элементу, который не представлен аргументом. X не должен содержать другой селектор отрицания.

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


Простой пример: исключая по классу

div:not(.class)

Выбрал бы все divэлементы без класса.class

div:not(.class) {
  color: red;
}
<div>Make me red!</div>
<div class="class">...but not me...</div>


Сложный пример: исключение по типу / иерархии

:not(div) > div

Выбрал бы все divэлементы, которые не являются потомками другогоdiv

div {
  color: black
}
:not(div) > div {
  color: red;
}
<div>Make me red!</div>
<div>
  <div>...but not me...</div>
</div>


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

За заметным исключением невозможности связывать / вкладывать :notселекторы и псевдоэлементы, вы можете использовать их вместе с другими псевдо селекторами.

div {
  color: black
}
:not(:nth-child(2)){
  color: red;
}
<div>
  <div>Make me red!</div>
  <div>...but not me...</div>
</div>


Поддержка браузера и т. Д.

:notэто селектор уровня CSS3 , главное исключение с точки зрения поддержки - это IE9 +

Спецификация также делает интересный момент:

:not()псевдо позволяет бесполезные селекторы должны быть записаны. Например :not(*|*), который не представляет никакого элемента вообще, или foo:not(bar), что эквивалентно, fooно с более высокой специфичностью.

SW4
источник
3
Это был ужин, хорошо задокументированный и хорошо проработанный ответ! #thumbsup
Джонатан Бредо Кристенсен
Хорошо, ваш пример :not(div) > divбудет работать только с прямыми родителями. А как насчет других дедов?
FindOut_Quran
Потрясающая информация! Как раз то, что мне было нужно! Спасибо!
Джейми
9

Просто хочу сказать, что приведенные выше ответы: not () могут быть очень эффективными в угловых формах, а не создавать эффекты или настраивать вид / DOM,

input.ng-invalid:not(.ng-pristine) { ... your css here i.e. border-color: red; ...}

Гарантирует, что при загрузке вашей страницы в полях ввода будут отображаться недопустимые значения (красные границы или фоны и т. Д.), Если к ним добавлены данные (т.е. они больше не являются нетронутыми), но являются недействительными.

BaneStar007
источник
7

пример

  [class*='section-']:not(.section-name) {
    @include opacity(0.6);
    // Write your css code here
  }

// Непрозрачность 0.6 все "section-", но не "section-name"

Hakan
источник
2

Вы можете использовать :not(.class)селектор, как упоминалось ранее.

Если вы заботитесь о совместимости Internet Explorer, я рекомендую вам использовать http://selectivizr.com/ .

Но не забудьте запустить его под Apache, иначе вы не увидите эффекта.

MelkorNemesis
источник
3
Что вы имеете в виду запустить его под Apache? Selectivizr - это
библиотека переднего плана
Он выполняет запрос ajax - это не работает без http-сервера.
MelkorNemesis
2

Используя :not()псевдокласс:

Для выбора всего, кроме определенного элемента (или элементов). Мы можем использовать :not() псевдокласс CSS . :not()Псевдо - класс требует CSSселектора в качестве аргумента. Селектор будет применять стили ко всем элементам, кроме элементов, указанных в качестве аргумента.

Примеры:

/* This query selects All div elements except for   */
div:not(.foo) {
  background-color: red;
}


/* Selects all hovered nav elements inside section element except
   for the nav elements which have the ID foo*/
section nav:hover:not(#foo) {
  background-color: red;
}


/* selects all li elements inside an ul which are not odd */
ul li:not(:nth-child(odd)) { 
  color: red;
}
<div>test</div>
<div class="foo">test</div>

<br>

<section>
  <nav id="foo">test</nav>
  <nav>Hover me!!!</nav>
</section>
<nav></nav>

<br>

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

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

/* This selector has a higher specificity than the #foo below */
#foo:not(#bar) {
  color: red;
}

/* This selector is lower in the cascade but is overruled by the style above */
#foo {
  color: green;
}
<div id="foo">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</div>

Виллем ван дер Веен
источник
0

Если вы хотите, чтобы конкретное меню класса имело определенный CSS, если отсутствующий класс вошел в систему :

body:not(.logged-in) .menu  {
    display: none
}
Михай
источник
-1

Как говорили другие, вы просто сказали: нет (.class). Для селекторов CSS я рекомендую посетить эту ссылку, она была очень полезна на протяжении всего моего путешествия: https://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048

div:not(.success) {
  color: red;
}

Псевдокласс отрицания особенно полезен. Допустим, я хочу выбрать все div, кроме той, которая имеет идентификатор контейнера. Приведенный выше фрагмент отлично справится с этой задачей.

Или, если бы я хотел выбрать каждый элемент (не рекомендуется), кроме тегов абзаца, мы могли бы сделать:

*:not(p) {
  color: green;
}
HBhering
источник