Приоритет CSS в теневой модели DOM ‹стиль›

Что правила приоритета CSS говорят о теге <style> в теневой модели DOM?

У меня есть элемент <component class="component">, файл CSS, включенный в <head>, с:

component {
    display: inline-block;
}

и тег <style> внутри некоторого теневого DOM с:

::slotted(.component) {
    display: block;
}

Если я правильно понимаю, первое правило должно иметь специфичность 0.0.1, так как оно имеет один элемент, а второе — специфичность 0.1.1, так как оно имеет один псевдоэлемент и один класс. Следовательно, второй является более конкретным и должен переопределять первый. Однако этого не происходит. В консоли разработчика (Chrome) я вижу оба правила, и ни одно из них не перечеркнуто, а на панели «вычисленные стили» я вижу «отображение: встроенный блок».

Более подробный пример по просьбе в комментариях:

<head>
    <style>
        /* "other-component" related styles: */
        other-component {
            display: inline-block;
        }
    </style>
</head>
<body>
    <some-component>
        #shadow-root:
            <style>
                slot[name=some-slot]::slotted(*) {
                    display: block; /* Only works with !important. */
                }
            </style>
            <slot name="some-slot"></slot>
        <!-- The actual ("light-dom") content: -->
        <other-component slot="some-slot"></other-component>
    </some-component>
</body>

person egst    schedule 26.02.2019    source источник
comment
Нет, я имел в виду слоты - нацеливание на элемент внутри :host с некоторым атрибутом слота. Я немного упростил, исходный селектор был [slot=...]::slotted(...)   -  person egst    schedule 28.02.2019
comment
Тогда как определяется теневой DOM и что находится в светлом DOM?   -  person Supersharp    schedule 28.02.2019
comment
Что ты имеешь в виду? Вы просите дать точное определение теневого DOM?   -  person egst    schedule 28.02.2019


Ответы (2)


Это поведение определено в черновике §3.3 CSS Scoping Module Level 1:

При сравнении двух объявлений, имеющих разные древовидные контексты, для обычных правил выигрывает объявление, предшествующее порядку дерева, включающего тень, [the first, global rule], а для важных правил — объявление, следующее позже в порядке дерева, включающем тень, [the second, ::slotted(*) rule].

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

В других мирах:

Стили, которые применялись до распространения, продолжают применяться после распространения.

person Supersharp    schedule 03.03.2019

У нас может быть самое подробное объяснение дизайна по адресу https://github.com/w3c/csswg-drafts/issues/2290#issuecomment-382465643

Несколько причин повлияли на текущий дизайн:

Мы намеренно вообще не привлекали конкретику. Это приведет к раскрытию деталей реализации компонента, что сделает код ненадежным — если компонент обновится и изменит точный используемый им селектор, он может начать переопределять внешние правила, которые ранее побеждали, или наоборот, и нет хорошего способа для компонента. пользователю понять или манипулировать этим.

Значит, надо решать по-другому. Порядок документов (последний шаг каскада) здесь не работает — он добавляет неожиданную зависимость от того, как именно вы загружаете пользовательский элемент, и может иметь интересную гонку

Таким образом, у нас остается Cascade Origin или что-то близкое к нему, что безоговорочно приводит к победе того или другого. На самом деле добавление нового источника в список не казалось хорошей идеей; неясно, как таблицы стилей пользователя и автора должны взаимодействовать с этим. Поэтому вместо этого мы добавляем еще один каскадный шаг для этого.

И, наконец, мы должны принять решение о том, кто победит. Мы уже знаем, что какой бы порядок мы ни выбрали, !important должен иметь обратный порядок; так уже работает каскадное происхождение. Таким образом, мы должны решить, выигрывает ли внешняя страница по умолчанию, но компонент выигрывает в !important, или наоборот. Мы решили, что первое имеет больше смысла; это означает, что нормальные стили автора компонента используются по умолчанию, стили пользователя компонента (!important или нет) могут переопределять их, а стили !important автора компонента можно использовать для блокировки стилей, которые должны оставаться такими, какие они есть. Обратный путь, похоже, также не удовлетворял прецедентам: это означало бы, что пользователи компонента не могут переопределять стили по умолчанию; им пришлось бы использовать !important для этого, возможно, мешая другим их стилям; и тогда у авторов компонентов не было бы возможности заблокировать стили.

person lkraav    schedule 23.05.2019