У меня есть ситуация с DOM, которая выглядит следующим образом:
A является предком B , который, в свою очередь, является предком C
Изначально A имеет стили, которые наследуются от B и C
Я хочу временно выделить B , присвоив ему выделенный класс
... однако ...
Я хочу «сбежать» выделение на C , поэтому оно меняется как можно меньше
Кажется, это невозможно в рамках каскадной парадигмы CSS. Единственный способ «отменить применение» стиля - это применить отменяющий стиль. Моя проблема в том, что код выделения находится в плагине, который хочет хорошо работать с существующим CSS произвольной страницы ... мои селекторы такие:
/* http://www.maxdesign.com.au/articles/multiple-classes/ */
.highlighted.class1 {
background-color: ...
background-image: ...
...
}
.highlighted.class2 {
...
}
/* ... */
.highlighted.classN {
...
}
Фон - сложный ... потому что, хотя он не унаследованный CSS свойство, изменение фона предка может изменить внешний вид потомка (если у них прозрачный фон). Так что это пример того, что вызывает нарушения, которые я пытаюсь отрицать.: - /
Есть ли примеры того, как люди подавляли наследование изменений таким образом? Возможно, используя такие уловки, как кеширование вычисляемых стилей ? Я ищу любую технику по умолчанию, которая может быть, по крайней мере, немного умнее, чем ловушка на уровне функций, которая говорит: «Эй, плагин выделил этот узел ... сделайте то, что вам нужно, чтобы визуально компенсировать».
ОБНОВЛЕНИЕ Я создал базовый JsFiddle этого сценария, чтобы прояснить обсуждение:
Если я правильно понимаю, вы хотите вырезать «дыру» на фоне предка. Единственный способ, которым я могу придумать, - это использовать <canvas>
, чтобы вырезать отверстие, а затем использовать полученное изображение в качестве фона предка.
Вот мой код: http://jsfiddle.net/7ku3g/24/
Я использовал логотип JS Fiddle в качестве водяного знака, поскольку вы не можете извлечь содержимое холста с помощью к нему привлечены ресурсы разных источников.
Обновление: вы также хотели бы прослушать resize
события для обновления фона при изменении размера окна.
Вы можете добавить .highlight .cClass
в две верхние группы CSS и установить color:initial
на .highlight .cClass
, например, так:
.aClass, .highlight .cClass {
background-image: url('http://hostilefork.com/shared/stackoverflow/parchment.jpg');
background-repeat: repeat;
}
.aClass, .bClass, .cClass, .xClass, .highlight .cClass {
border : 2px solid #000;
margin: 20px;
padding: 20px;
}
.highlight .cClass {
color: initial;
}
Единственная проблема, в этом примере , это то, что фоновая позиция изменяется. Но это лучшее, что я придумал.
Я бы установил фон .class таким же, как и класс .a с css, но если вы хотите, чтобы они совпали, вам придется также изменить стиль положения фона.
У меня есть решение, которое помогает с не фоновыми стилями. Вы можете увидеть скрипку http://jsfiddle.net/7ku3g/83/ , которая является лишь грубым понятием. Некоторые ключевые моменты: 1) обязательно, чтобы добавленный элемент styleControl
был добавлен к внутреннему самому содержащему элементу. Например, у вас был добавлен класс .highlight
к div .bClass
, но в нем был еще один элемент полной обертки, blockquote
. 2) Вы хотите удалить элемент styleControl
после удаления класса выделения.
В общем, идея состоит в том, чтобы сначала добавить невидимый элемент стиля в в самой внутренней обертке, а затем использовать общий селектор родного брата ~
и селектор :not
для стилизации дальнейших элементов вниз. Опять же, это не решает ваши проблемы с фоном , но, похоже, это способ помочь решить истинные наследуемые свойства, поскольку эти стили НЕ применяются к div-обертке, а только к недавно созданному первому брату в группе и свойства, примененные на основе этого родного брата, только к тем, к которым они должны применяться.
Одна из проблем, связанных с этой техникой, заключается в том, что любой «голый текст» (см. http://jsfiddle.net/7ku3g/84/ ) не может быть стилизован. Так что это не полное решение вашей проблемы. РЕДАКТИРОВАТЬ: Для таких случаев может сработать захват и добавление тщательно созданного span
вокруг этих обнаженных узлов. Нечто похожее на: Стиль определенного символа в строке .
CSS
.highlight.bClass {
background-image: url('http://hostilefork.com/shared/stackoverflow/cc-by-nc-nd.png');
background-repeat: repeat;
}
.highlight.bClass .styleControl {
width: 0;
height: 0;
position: absolute;
}
.highlight.bClass .styleControl ~ *:not(.cClass) {
color: red;
}
ОБНОВЛЕНИЕ: Некоторое дальнейшее объяснение, основанное на комментариях HostileFork. Во-первых, мое решение здесь имеет значение только в том случае, если есть дочерний элемент, который вы хотите запретить наследовать стили (фактические наследуемые стили), которые вы добавляете. Во-вторых, может потребоваться добавить несколько, в зависимости от того, насколько глубоко они вложены. Вот несколько псевдокодов html для обсуждения:
<div> (containing licensed material)
<childA1> (this is the wrapping blockquote in your example; could be anything)
<scriptAddedStyleElementB0>
<childB1>content<endchildB1> (apply styles)
<childB2>content<endchildB2> (don't apply styles)
<childB3> (don't apply styles because a child is not having styles applied)
<scriptAddedStyleElementC0>
<childC1> (apply styles)
<!-- noScriptAddedStyleElementD0 -->
<childD1>content<endchildD1>
<childD2>content<endchildD2>
<endchildC1>
<childC2>content<endchildC2> (don't apply styles)
<endchildB3>
<end-childA1>
<end-div1>
Вы нацелены на самый внешний div
, чтобы применить класс highlight
, но на некоторых детей вы не хотите, чтобы на них влияли. Обратите внимание, что A1 и B3 сами не содержат никакого контента (текста / изображений), они просто содержат другие элементы. Это «обертки» в моем использовании этого термина (они просто используются для группировки своих детей, хотя у них может быть стиль).
Чтобы ответить на ваш вопрос «когда нужно прекратить погружение», это когда вы достигаете точки, когда вам больше не нужно наследовать стили. В приведенном выше примере необходимо добавить 2 элемента оформления, один в B0 и один в C0, но не в D0. Это связано с тем, что общий селектор братьев и сестер ~
применяется только к элементам, у которых один и тот же родительский элемент и которые следуют за этим братом. Таким образом, B0 собирается применить стили к B1, но не к B2 (нелицензионному) или B3 (содержит нелицензионное). Элемент C0 собирается применить стили к C1 (и его лицензированным дочерним элементам D1 и D2), но избегает стилизации C2. Содержимое B2 и C2 будет по-прежнему наследовать исходные стили от div-оболочки (C2 посредством B3), в то время как B1, C1, D1, D2 получат стиль лицензирования.
Трудности в этом заключаются в следующем: 1) более ранние версии IE (7 и 8) не распознают некоторые из этих CSS, в частности селектор :not
. Это может потенциально обойтись. 2) мои предыдущие заметки о «голом тексте» или контенте. Если бы B3 выглядел следующим образом:
<childB3>
<scriptAddedStyleElementC0>
Some unwrapped text
<childC1>...<endchildC1>
Some other unwrapped text and an <img> tag
<childC2>...<endchildC2>
More unwrapped text
<endchildB3>
Если для лицензирования нужно было оформить распакованный текст B3 (в вашем примере он стал красным), вам нужно было бы найти все текстовые узлы с помощью javascript и обернуть их в span
элементы для применения стиля, потому что если вы примените стиль к B3, то он унаследует C2, который вам не нужен.
Нет сомнений, что то, что вы ищете, трудно достичь. Это было бы невозможно с помощью CSS до появления общего селектора, и это может стать проще с обсуждаемыми стандартами CSS4 (для этой ситуации может быть использована возможность стилизовать родительские элементы от дочерних элементов).