如何在自定义元素中提供后备 CSS-value?

How to provide a fallback CSS-value within a custom element?

我有一个自定义网络组件,它基本上是一个 SVG 图标:

<custom-icon>
    <svg>{svg-stuff}</svg>
</custom-icon>

我希望能够通过应用 CSS 来更改它的大小:

custom-icon {
    width: 20px;
}

但我也希望在未应用 CSS 时有一个后备默认值。但是,当我内联一些 CSS 时,比如 <custom-icon style="width:15px"> 它只会覆盖我之后申请的所有 CSS 。如果没有自定义 CSS?

,我怎样才能让默认的“15px”只适用

MWE:

class CustomIcon extends HTMLElement {
  constructor() {
    super();
    
    let size = "100px"
    
    this.style.height = size;
    this.style.width = size;
    
    this.style.background = "firebrick"
    this.style.display = "block"
  }
}

window.customElements.define('custom-icon', CustomIcon);
custom-icon {
  --icon-size: 50px;
  height: var(--icon-size);
  width: var(--icon-size);
}
<custom-icon />

订单按照the cascade.

应用 通过 style 属性应用的

CSS 位于级联的底部。实际上,如果您在返回到样式表时通过属性指定。

因此 20px 是您未指定 15px 时的后备方案。


您可以使用另一个带有不太具体选择器的规则集来编写后备CSS(尽管唯一比单一类型选择器更不具体的东西(例如custom-icon) 是通用选择器 (*),这没有用)所以你需要用 more 特定的东西替换 custom-icon

另一种选择是采用大锤式方法并制定规则集中的每条规则 !important


最好的选择可能是首先修复可能导致您的 CSS 丢失的任何情况。

您可以考虑数据属性,然后将该属性用作自定义 属性 的后备。

您可以在下面看到,在我们删除自定义 属性(通过设置 initial)之前,尺寸不会有任何影响

class CustomIcon extends HTMLElement {
  constructor() {
    super();
    
    this.style.height = `var(--icon-size, ${this.getAttribute('size')})`;
    this.style.width = `var(--icon-size, ${this.getAttribute('size')})`;
    
    this.style.background = "firebrick"
    this.style.display = "block"
  }
}

window.customElements.define('custom-icon', CustomIcon);
custom-icon {
  --icon-size: 50px;
  margin:5px;
}
<custom-icon size="15px"></custom-icon>
<custom-icon size="25px"></custom-icon>
<custom-icon size="2050px"></custom-icon>


<custom-icon size="200px" style="--icon-size:initial"></custom-icon>

了解initial使用的相关问题:

自定义 属性 初始未设置的另一个示例。

class CustomIcon extends HTMLElement {
  constructor() {
    super();

    this.style.height = `var(--icon-size, ${this.getAttribute('size')})`;
    this.style.width = `var(--icon-size, ${this.getAttribute('size')})`;

    this.style.background = "firebrick"
    this.style.display = "block"
  }
}

window.customElements.define('custom-icon', CustomIcon);
custom-icon {
  margin: 5px;
}

.set {
  --icon-size: 50px;
}
<div class="set">
  <custom-icon size="15px"></custom-icon>
  <custom-icon size="25px"></custom-icon>
  <custom-icon size="2050px"></custom-icon>
</div>

<custom-icon size="200px" ></custom-icon>

如果您的自定义元素的内容被封装在阴影DOM中,这是推荐的做法,您可以使用:host伪class来定义默认样式.

然后,如果您为自定义元素定义全局样式,它将覆盖使用 :host 定义的样式。

customElements.define( 'custom-icon', class extends HTMLElement {
  constructor() {
    super()
    let size = 100
    this.attachShadow( { mode: 'open' } )
        .innerHTML = `
          <style>
            :host {
               display: inline-block ;
               height: ${size}px ;
               width: ${size}px ;
               background-color: firebrick ; 
               color: white;
            }
          </style>
          <slot></slot>`
  }
} )
custom-icon#i1 {
  --icon-size: 50px;
  height: var(--icon-size);
  width: var(--icon-size);
}
<custom-icon id="i1">sized</custom-icon>
<hr>
<custom-icon>default</custom-icon>