Стилизация дочернего элемента теневого корня в Shadow DOM

Я пытаюсь стилизовать дочерний элемент теневого корня DOM.
Это определяет настраиваемый элемент с именем element-el, который имеет span класс с именем 'x' с буквой x в нем, которую я хочу, для состояния по делу, чтобы быть красным.

class El extends HTMLElement {
    constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        shadow.innerHTML = '<span class="x">X</span>';
    }
}
customElements.define ('element-el',El);

Я пробовал эти стили CSS:

element-el::slotted(.x) {
  color:red;
}
element-el::host .x {
  color:red;
}
element-el:host .x {
  color:red;
}
element-el::shadow .x {
  color:red;
}
element-el /deep/ .x {
  color: red;
}
element-el::content .x {
  color:red;
}

X не становится красным. Я использую Chrome 56, который должен это поддерживать ...

Я хочу стилизовать его, не помещая элемент style внутри теневого DOM.
Вот код: http://codepen.io/anon/pen/OpRLVG?editors=1111

РЕДАКТИРОВАТЬ:
Эта статья предполагает, что можно стилизовать теневых дочерних элементов из внешнего файла CSS - они просто неверны?


person Yuval A.    schedule 06.03.2017    source источник


Ответы (4)


По-видимому, проблема заключается в том, что вы пытаетесь использовать глобальный CSS для стилизации элементов теневого дерева.

Вы можете использовать псевдоселектор :host , однако для этого вам нужно будет разместить стиль внутри содержимого теневого дерева.

Внесите следующие изменения в свой javascript:

class El extends HTMLElement {

    constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        var innerHTML = '';
        innerHTML += '<style>';
        innerHTML += ':host(element-el.red) span {color: red}';
        innerHTML += ':host(element-el.green) span {color: green}';
        innerHTML += ':host(element-el.blue) span {color: blue}';
        innerHTML += '</style>';      
        innerHTML += '<span class="x">X</span>';      
        shadow.innerHTML = innerHTML;
    }

}

customElements.define ('element-el',El);

Проверьте функциональный пример в вашем updated codepen.

person Romulo    schedule 06.03.2017
comment
Спасибо за ответ. Я говорил об этом: developer.mozilla.org/en-US/ docs / Web / Web_Components /, когда я подумал, что могу стилизовать дочерние элементы теневой DOM из внешнего CSS (см. «Файл CSS» в части «Пример») - они просто ошибаются в статье? - person Yuval A.; 06.03.2017
comment
Ознакомьтесь с приведенным ими примером по адресу: mdn.mozillademos.org / en-US / docs / Web / Web_Components /. Оба объявления CSS, использующие псевдоселектор ::slotted, не работают в Chrome. - person Romulo; 06.03.2017

Простое решение - определить класс x в Shadow DOM:

class El extends HTMLElement {
    constructor() {
        super()
        this.attachShadow({mode:'open'})
            .innerHTML = `
               <style>
                  .x { color: red } 
               </style>
               <span class="x">X</span>`
    }
}
customElements.define ('element-el',El)
<element-el></element-el>

Примечание: из-за инкапсуляции стиля Shadow DOM вам всегда нужно помещать <style> элемент в Shadow DOM, независимо от того, используется ли решение Romulo :host, прямое объявление класса (см. выше) или внешней таблицы стилей.

Конечно, если вы используете унаследованное свойство CSS (например, color), которое будет применяться ко всему вашему теневому содержимому DOM, вы можете просто использовать обычный CSS:

class El extends HTMLElement {
    constructor() {
        super();
        var shadow = this.attachShadow({mode:'open'});
        shadow.innerHTML = '<span class="x">X</span>';
    }
}
customElements.define ('element-el',El);
element-el {
    color: red;
}
<element-el></element-el>   

person Supersharp    schedule 06.03.2017
comment
Спасибо за ответ. Я говорил об этом: developer.mozilla.org/en-US/ docs / Web / Web_Components /, когда я подумал, что могу стилизовать дочерние элементы теневой DOM из внешнего CSS (см. «Файл CSS» в части «Пример») - они просто ошибаются в статье? - person Yuval A.; 06.03.2017
comment
@YuvalA. да, они ошибаются со стилями ::slotted. Они не работают, потому что находятся не в нужном месте (в теневом элементе ‹style› DOM). - person Supersharp; 06.03.2017

Это может помочь кому-то еще в подобной ситуации.

В моем случае у меня есть:

<svg class="icon">
    <use xlink:href="#my-icon"></use>
</svg>

и для доступа к отображаемому значку в # shadow-root я использую:

.icon use {
  fill: #f80;
}
person A. D'Alfonso    schedule 07.12.2017
comment
Насколько это актуально? - person ADJenks; 19.03.2019

Если element-el находится в shadow-dom, вам должен помочь следующий селектор css:

<parent Element of shadow-root> /deep/ element-el span {
    color:red;
}

Выберите элемент, содержащий shadow-dom, затем выберите с помощью / deep / все дочерние элементы, а затем выберите элементы span.

/ deep / еще не является стандартом HTML, но в Chrome и Firefox он должен работать.

person frontend-trends    schedule 15.08.2017
comment
deep устарел - person ; 17.02.2018