疑似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
相关产品推荐
相关产品推荐

