【问题标题】:Applying selection style to slotted elements?将选择样式应用于开槽元素?
【发布时间】:2021-03-14 04:05:14
【问题描述】:

我正在尝试将::selection 样式应用于 Web 组件中的开槽元素。

这里有一个小代码来说明这个问题:

window.customElements.define('x-widget', class extends HTMLElement {
    constructor() {
        super();

        this.attachShadow({mode: 'open'});

        const template = document.createElement('template');
        template.innerHTML = `
            <div>TEMPLATE</div>
            <div><slot></slot></div>
        `;

        const style = document.createElement('style');
        style.textContent = `
            :host {
                display: content;
                contain: content;
                color: red;
            }
    
            :host::selection, ::selection {
                background: red;
                color: white;
            }
    
            ::slotted(::selection) {
                background: red;
                color: white;
            }
        `;

        this.shadowRoot.appendChild(style);
        this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
});
<x-widget>CONTENT1</x-widget>
<x-widget><div>CONTENT2</div></x-widget>

这是一个演示:https://jsfiddle.net/ov4xmqsr/

选择样式适用于除&lt;div&gt;CONTENT2&lt;/div&gt; 之外的所有文本。有没有办法在组件中使用伪元素选择器?

【问题讨论】:

    标签: css css-selectors web-component pseudo-element


    【解决方案1】:

    你不能,因为 slotted 内容没有移动到 shadowDOM,它保留在 ligthDOM 中。

    您在 ligthDOM(在本例中为主 DOM)中设置插槽内容的样式

    更详细的答案见:::slotted CSS selector for nested children in shadowDOM slot

    我添加了额外的 CSS 来显示:

    • 使用变量(穿透 shadowDOM)来声明颜色

    • 使用#selectable DIV 包装器选择两个自定义元素
      亲自看看x-widget ::selection 选择器会做什么

    Select all text:
    <div id=selectable>
      <x-widget>CONTENT1</x-widget>
      <x-widget><div>CONTENT2</div></x-widget>
    </div>
    <style>
      body {
        --selectionBackground: green; --selectionColor: white;
        font-size: 2em;
      }
      #selectable ::selection {
        background: var(--selectionBackground); color: var(--selectionColor);
        font-weight: bold;
      }
    </style>
    <script>
      window.customElements.define('x-widget', class extends HTMLElement {
        constructor() {
          const template = document.createElement('template');
          template.innerHTML = `<div>TEMPLATE</div><div><slot></slot></div>`;
          const style = document.createElement('style');
          style.textContent = `
                ::selection { /* colors only template text, not slot content */
                    background: var(--selectionBackground);
                    color: var(--selectionColor);
                }
                ::slotted(*) {  /* selectors select HTMLElements! */
                    color: red; /* CONTENT1 is TEXT, NOT an HTMLElement! */
                }`;
          super().attachShadow({mode: 'open'})
                 .append(style, template.content.cloneNode(true));
        }});
    </script>

    【讨论】:

      猜你喜欢
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 2019-12-11
      相关资源
      最近更新 更多