CSS-отрицание псевдокласс: not() для элементов parent/ancestor

Это сводит меня с ума:

HTML:

<div><h1>Hello World!</h1></div>

CSS

*:not(div) h1 { color: #900; }

Не читает ли это: "Выберите все элементы h1, у которых есть предок, который не является элементом div...?" Таким образом, "Hello World!" не должен быть окрашен в красный цвет, но он все еще есть.

Для вышеуказанной разметки добавление дочернего комбинатора работает:

*:not(div) > h1 { color: #900; }

Но не влияет на элемент h1, если он не является дочерним элементом элемента div. Например:

<div><article><h1>Hello World!</h1></article></div>

Вот почему я хотел бы указать элемент h1 как потомок, а не дочерний элемент div. Кто-нибудь?

Ответ 1

Не читает ли это: "Выберите все элементы h1, у которых есть предок, который не является элементом div...?"

Это так. Но в типичном HTML-документе каждый h1 имеет по крайней мере двух предков, которые не являются элементами div, и эти предки - это не что иное, как body и html.

Это проблема с попыткой фильтрации предков с помощью :not(): он просто не работает надежно, особенно если :not() не может быть квалифицирован каким-либо другим селектором, таким как селектор типа или селектор классов, например. .foo:not(div). У вас будет намного проще использовать стили для всех элементов h1 и переопределить их с помощью div h1.

В Селекторы 4, :not() были расширены, чтобы принимать полные комплексные селектор, содержащие комбинаторы, включая комбинатор потомков. Будет ли это реализовано в быстром профиле (и, следовательно, в CSS), еще предстоит проверить и подтвердить, но как только он будет реализован, вы сможете использовать его для исключения элементов с определенными предками. Из-за того, как работают селекторы, отрицание должно выполняться самим элементом, а не предком, чтобы надежно работать, и поэтому синтаксис будет выглядеть несколько иначе:

h1:not(div h1) { color: #900; }

Любой, кто знаком с jQuery, быстро укажет, что этот селектор работает в jQuery сегодня. Это один из различий между Selector 3 :not() и jQuery :not(), который Selectors 4 исправляет.

Ответ 2

Элемент <html> не является <div>. Элемент <body> не является <div>.

Таким образом, условие "имеет предка, не являющегося <div>", будет истинным для всех элементов.

Если вы не можете использовать селектор > (child), я не думаю, что вы можете делать то, что вы пытаетесь сделать - на самом деле это не имеет смысла. В вашем втором примере <article> не является div, поэтому также соответствует *:not(div).