【问题标题】:How to provide a fallback CSS-value within a custom element?如何在自定义元素中提供后备 CSS 值?
【发布时间】:2020-05-03 02:51:58
【问题描述】:

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

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

我希望能够通过像这样应用 CSS 来改变它的大小:

custom-icon {
    width: 20px;
}

但我也希望在未应用 CSS 时有一个后备默认值。但是,当我内联一些 CSS,如 &lt;custom-icon style="width:15px"&gt; 时,它只会覆盖我之后应用的所有 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);
}
&lt;custom-icon /&gt;

【问题讨论】:

  • 像这样向组件添加一个类 ... 并将 CSS 标记声明更改为第一类:custom-icon { => .custom-class { 宽度:15px; }
  • have a fallback default value when no CSS is applied 这是什么意思?为什么不应用 css?
  • 如果你有内联样式,你的 css 必须使用 !important - 这是覆盖内联样式的唯一方法 - 但使用时要小心,因为它可能成为特异性噩梦
  • @MaksimTikhonov 你能相应地修改sn-p吗?我不确定你的意思
  • 那么我想这样做的方法是将您的裸选择器作为您的默认值,然后为您的覆盖添加一个类

标签: javascript css web-component custom-element css-variables


【解决方案1】:

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

然后,如果您为自定义元素定义一种全局样式,它将覆盖使用: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>

【讨论】:

  • 我知道。在 Minimal(!)WE 中它只是没有意义。所以,感谢您的提示,但这并不能真正回答问题,是吗?
  • @leonheess 实际上确实如此。请参阅添加的示例。
  • 嗯,很有趣。现在我得到了你的方法,它实际上很有帮助!
【解决方案2】:

订单按照the cascade申请。

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

所以20px 是您未指定15px 时的后备。


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

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


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

【讨论】:

    【解决方案3】:

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

    您可以在下面看到,直到我们删除自定义属性(通过设置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使用的相关问题:CSS custom properties (variables) for box model

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

    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>

    【讨论】:

    • @leonheess 这里是一些相关的答案,以获得更多关于 CSS 变量及其后备的强大内容:stackoverflow.com/q/53239880/8620333 / stackoverflow.com/a/49618941/8620333
    • 在自定义元素中,constructor 中不允许对属性进行读取访问。它不允许使用new CustomIcondocument.createElement('custom-icon') 动态创建元素。您也称它们为 数据属性 - 该术语是为 data- 前缀属性保留的。
    • html.spec.whatwg.org/multipage/… 自定义元素构造函数和反应的要求 [...] 不得检查元素的属性和子元素,如在非升级情况下不会出现,并且依赖升级会降低元素的可用性。
    • @connexo 你有什么推荐的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2014-10-02
    • 2021-12-14
    相关资源
    最近更新 更多