Почему мой jQuery: not () не работает в CSS?

У меня этот макет:

Sectors

С помощью этих правил CSS:

 #sectors { width: 584px; background-color: #ffd; margin: 1.5em; border: 4px dashed #000; padding: 16px; overflow: auto; } #sectors > h1 { font-size: 2em; font-weight: bold; text-align: center; } #sectors > div { float: left; position: relative; width: 180px; height: 240px; margin: 16px 0 0 16px; border-style: solid; border-width: 2px; } #sectors > div::after { display: block; position: absolute; width: 100%; bottom: 0; font-weight: bold; text-align: center; text-transform: capitalize; background-color: rgba(255, 255, 255, 0.8); border-top: 2px solid; content: attr(id) ' - ' attr(class); } #sectors > div:nth-of-type(3n+1) { margin-left: 0; } #sectors > div.alpha { color: #b00; background-color: #ffe0d9; } #sectors > div.beta { color: #05b; background-color: #c0edff; } #sectors > div.gamma { color: #362; background-color: #d4f6c3; } 

Я использую jQuery для добавления unassigned classа в сектора, которые иначе не имеют один из classов alpha , beta или gamma :

 $('#sectors > div:not(.alpha, .beta, .gamma)').addClass('unassigned'); 

Затем я применяю к этому classу несколько разных правил:

 #sectors > div.unassigned { color: #808080; background-color: #e9e9e9; opacity: 0.5; } #sectors > div.unassigned::after { content: attr(id) ' - Unassigned'; } #sectors > div.unassigned:hover { opacity: 1.0; } 

И все работает безупречно в современных браузерах.

Интерактивный просмотр jsFiddle

Но, видя, что :not() селектор в jQuery основан на :not() в CSS3 , я думал, что могу перенести его непосредственно в таблицу стилей, поэтому мне не пришлось бы полагаться на добавление дополнительного classа с помощью jQuery. Кроме того, я не очень заинтересован в поддержке более старых версий IE, а другие браузеры отлично поддерживают селектор :not() .

Поэтому я стараюсь изменить .unassigned часть выше (зная, что в моем макете будут только сектора A, Β и Γ):

 #sectors > div:not(.alpha, .beta, .gamma) { color: #808080; background-color: #e9e9e9; opacity: 0.5; } #sectors > div:not(.alpha, .beta, .gamma)::after { content: attr(id) ' - Unassigned'; } #sectors > div:not(.alpha, .beta, .gamma):hover { opacity: 1.0; } 

Но как только я это делаю, он перестает работать – во всех браузерах ! Мои неназначенные сектора не выделены серым цветом, исчезли или помечены как «Не назначенные».

Обновлен, но не так интерактивен jsFiddle preview

Почему селектор :not() работает в jQuery, но не работает в CSS? Не должно ли он работать одинаково в обоих местах, поскольку jQuery утверждает, что он является «совместимым с CSS3», или есть что-то, что мне не хватает?

Есть ли способ обхода CSS для этого или мне придется полагаться на скрипт?

Почему селектор :not() работает в jQuery, но не работает в CSS? Не должно ли он работать одинаково в обоих местах, поскольку jQuery утверждает, что он является «совместимым с CSS3», или есть что-то, что мне не хватает?

Возможно, это должно произойти , но оказалось, что это не так : jQuery расширяет селектор :not() таким образом, что вы можете передать ему любой селектор , каким бы сложным он ни был, и я подозреваю, что основная причина этого для контроля четности с .not() , который также принимает любой произвольно сложный селектор и соответственно фильтрует. Он делает так, чтобы поддерживать синтаксис, подобный CSS, но он простирается от того, что определено в стандарте.

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

 /* * Select any section * that's neither a child of body with a class * nor a child of body having a descendant with a class. */ $('section:not(body > [class], body > :has([class]))') 

Предварительный просмотр jsFiddle

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

Теперь, с другой стороны, псевдоclass classа :not() в Селекторах 3 , сам по себе очень ограничен. Вы можете передать только один простой селектор в качестве аргумента для :not() . Это означает, что вы можете передавать только один из них за раз:

  • Универсальный селектор ( * ), необязательно с пространством имен
  • Селектор типов ( a , div , span , ul , li и т. Д.), Необязательно с пространством имен
  • Селектор атрибутов ( [att] , [att=val] и т. Д.), Необязательно с пространством имен
  • Селектор classов ( .class )
  • Селектор ID ( #id )
  • :pseudo-class ( :pseudo-class )

Итак, вот различия между селектором jQuery :not() селектором :not() текущего стандарта :

  1. Прежде всего, чтобы ответить на вопрос напрямую: вы не можете передать список селекторов, разделенных запятыми. 1 Например, хотя данный селектор работает в jQuery, как показано в скрипте, он недействителен CSS:

     /* If it's not in the Α, Β or Γ sectors, it's unassigned */ #sectors > div:not(.alpha, .beta, .gamma) 

    Есть ли способ обхода CSS для этого или мне придется полагаться на скрипт?

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

     #sectors > div:not(.alpha):not(.beta):not(.gamma) 

    Это не делает селектор намного длиннее, но непоследовательность и неудобства остаются очевидными.

    Обновлен интерактивный просмотр jsFiddle

  2. Вы не можете комбинировать простые селектора в составных селекторах для использования с :not() . Это работает в jQuery, но недействителен CSS:

     /* Do not find divs that have all three classes together */ #foo > div:not(.foo.bar.baz) 

    Вам нужно разделить его на несколько отрицаний (а не просто на цепочку!), Чтобы сделать его действительным. CSS:

     #foo > div:not(.foo), #foo > div:not(.bar), #foo > div:not(.baz) 

    Как вы можете видеть, это еще более неудобно, чем точка 1.

  3. Вы не можете использовать комбинаторы. Это работает в jQuery, но не в CSS:

     /* * Grab everything that is neither #foo itself nor within #foo. * Notice the descendant combinator (the space) between #foo and *. */ :not(#foo, #foo *) 

    Это особенно неприятный случай, прежде всего потому, что у него нет надлежащего обходного пути. Есть некоторые способы обхода ( 1 и 2 ), но они почти всегда зависят от структуры HTML и поэтому очень ограничены в утилите.

  4. В браузере, который реализует querySelectorAll() и селектор :not() , используя :not() в селекторной строке способом, который делает его допустимым селектором CSS, заставит метод напрямую возвращать результаты, вместо того, чтобы возвращаться к Sizzle (механизм переключения jQuery, который реализует расширение :not() ). Если вы являетесь приверженцем производительности, это положительно незначительный бонус, который вы обязательно сэлизуете.

Хорошей новостью является то, что Selectors 4 улучшает селектор :not() , чтобы разрешить список сложных селекторов, разделенных запятыми. Комплексный селектор – это просто простой или составной селектор или целая цепь составных селекторов, разделенных комбинаторами. Короче говоря, все, что вы видите выше.

Это означает, что приведенные выше примеры jQuery станут действительными селекторами уровня 4, что сделает псевдоclass намного полезнее, когда реализация CSS начнет поддерживать его в ближайшие годы.


1 Хотя в этой статье говорится, что вы можете передать список селекторов, разделенных запятыми, на :not() в Firefox 3, вы не должны быть в состоянии. Если это работает в Firefox 3, как утверждается в этой статье, то это потому, что ошибка в Firefox 3, для которой я больше не могу найти билет, но он не должен работать, пока будущие браузеры не будут внедрять будущие стандарты. Видя, как часто эта статья цитируется до настоящего времени, я оставил комментарий к этому вопросу, но, видя также, сколько лет статья и как редко сайт обновляется, я действительно не рассчитываю на то, что автор вернется, чтобы исправить Это.

  • Разница между CSS-селектором и фильтром jQuery?
  • Должны ли все события jquery быть привязаны к $ (документу)?
  • Селектор jQuery для метки флажка
  • Что такое fastest children () или find () в jQuery?
  • jQuery выбрать все, кроме первого
  • поиск jQuery и контекст
  • Случай селектора CSS для атрибутов
  • Как работают PrimeFaces Selectors как в update = "@ (. MyClass)"?
  • Как получить выражение селектора jQuery в виде текста?
  • addID в jQuery?
  • Как я могу определить, возвращает ли селектор null?
  • Давайте будем гением компьютера.