Почему это объявление CSS: not () не отфильтровывается? - PullRequest
4 голосов
/ 17 декабря 2011

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

div:not(.no) span{background-color:#00f;}

Вот HTML

<div>
    <span>yes 1</span>
</div>
<div class="no">
        <span>no 1</span>
</div>
<div class="no">
    <div>
           <span>no 2</span>
    </div>
</div>

Два вопроса:

  1. Почему мой CSS применяется как к да 1, так и к 2?
  2. Почему все это ломается, если я переключаюсь на универсальный селектор?

    *:not(.no) span{background-color:#00f;}
    

Вот код в JSFiddle: http://jsfiddle.net/stephaniehobson/JtNZm/

Ответы [ 3 ]

8 голосов
/ 17 декабря 2011
  1. Оба родительских элемента span элементов div не имеют класса no, независимо от того, есть ли у других предков его:

    <div> <!-- This is div:not(.no), pretty much a given -->
        <span>yes 1</span>
    </div>
    
    <div class="no"> <!-- In this case, although this is div.no... -->
        <div>        <!-- ... this is div:not(.no)! -->
               <span>no 2</span>
        </div>
    </div>
    
  2. Оба html и body, которые являются предками ваших элементов div и span, удовлетворяют *:not(.no) при использовании универсального селектора (или, скорее, при пропускеселектор типа).Это заставляет все ваших span элементов иметь цвет фона.

Одним из решений этой проблемы является привязка фильтра отрицания к элементу body с помощьюдочерний комбинатор, если ваши элементы div верхнего уровня всегда будут потомками body:

body > div:not(.no) span { background-color: #00f; }

jsFiddle demo

Другое решение состоит в том, чтобы простоиспользовать стили переопределения.

4 голосов
/ 17 декабря 2011

BoltClock правильный. Это может иметь больше смысла, если вы сформулируете селектор следующим образом:

Выберите любой элемент span
который произошел от div элемента
чье значение class не содержит слова no.

Каждый из выбранных span в вашем примере фактически происходит от div, значение которого class не содержит слова no - тот факт, что второй из них также происходит от div чье class значение содержит содержит слово no не отменяет (ха!) Предыдущее утверждение.

Интересно, я бы поспорил, что если вы переместите второй no вниз на уровень, второй span все равно будет соответствовать. В CSS нет понятия близости элементов, поэтому любого предка div должно хватить для соответствия селектору, независимо от того, «ближе» он к span или нет.

0 голосов
/ 17 декабря 2011

Я думаю, что лучший выбор - разделить ваше утверждение на 2:

div span { background-color:#00f; }
.no span { background-color:#fff; }

Эффект можно увидеть здесь: http://jsfiddle.net/JHTqp/

...