You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

疑似Chrome Bug:Web组件应用特定样式时CSS last-of-type不更新

Chrome中Web组件的:last-of-type选择器失效问题

问题背景

开发了tst-list Web组件,内部包含带加号图标的tst-add组件(ID为ADD)。点击添加按钮会创建tst-wrapper组件并添加到tst-list中,每个tst-wrapper根据自身位置显示排序按钮:第一项隐藏PREV按钮,最后一项隐藏NEXT按钮。该逻辑在Firefox中运行正常,但在Chrome v109中存在异常。

失效表现

点击#ADD按钮5次后,所有tst-wrapper项的NEXT按钮均不显示。

正常表现

正常状态下,除最后一项外,其他tst-wrapper项的NEXT按钮正常显示;除第一项外,其他项的PREV按钮正常显示。

问题原因

tst-add组件中的以下样式会导致:last-of-type选择器失效,移除该样式后功能恢复正常:

:host(:active) #ICON {
   fill: red;
}

临时修复方案

通过隐藏再显示前一个元素触发CSS样式更新,取消注释以下代码即可生效:

// --- START OF HACK
child.previousElementSibling.style.display="none"
setTimeout(() =>child.previousElementSibling.style.display="block");
// --- END OF HACK

最小可复现代码

JavaScript代码

customElements.define('tst-add', class extends HTMLElement {
  constructor() {
    super().attachShadow({mode: 'open'})
           .append(document.getElementById('TEMPLATE_add').content.cloneNode(true));
  }
});
customElements.define('tst-wrapper', class extends HTMLElement {
  constructor() {
    super().attachShadow({mode: 'open'})
           .append(document.getElementById('TEMPLATE_wrapper').content.cloneNode(true));
  }
});

const WRAPPER_LOCAL_NAME = 'tst-wrapper';
customElements.define('tst-list', class extends HTMLElement {
  constructor() {
    super().attachShadow({mode: 'open'})
           .append(document.getElementById('TEMPLATE_list').content.cloneNode(true));
    this.shadowRoot.getElementById('ADD')
        .addEventListener('click', (evt) => this.addChild(evt));
  }
  addChild(evt) {
    const child = document.createElement(WRAPPER_LOCAL_NAME);
    child.textContent = "NEW"
    this.appendChild(child);
    if (child.previousElementSibling) {
      // --- START OF HACK
      //child.previousElementSibling.style.display="none"
      //setTimeout(() =>child.previousElementSibling.style.display="block");
      // --- END OF HACK
    }
  }
});

HTML代码

<template id="TEMPLATE_add">
  <style>
    :host(:active) #ICON {
       fill: red;
  }
  </style>
  <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000" draggable="false" id="ICON">
      <path d="M0 0h24v24H0z" fill="none"></path>
      <path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"></path>
  </svg>
</template>
<template id="TEMPLATE_wrapper">
  <style>
    :host(:first-of-type) #PREV,
    :host(:last-of-type) #NEXT {
        display: none;
  }
  </style>
  <div id="CONTAINER">
      <slot></slot>
      <button id="PREV"   type="button">PREV</button>
      <button id="NEXT"   type="button">NEXT</button>
  </div>
</template>
<template id="TEMPLATE_list">
  <div id="CONTAINER">
      <div id="LIST" part="list">
          <slot id="SLOT"></slot>
      </div>
      <tst-add id="ADD"></tst-add>
  </div>
</template>

<tst-list></tst-list>

内容的提问来源于stack exchange,提问作者run_the_race

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 17:11:10