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

Chromium系浏览器中::part()与其他选择器链式失效的替代方案咨询

问题描述

尝试将:disabled、:not([disabled])和/或:not([aria-label=''])与::part()链式使用时,在Chrome、Edge这类Chromium系浏览器中无法生效,而客户仅使用这两款浏览器。需要匹配Shadow Root中同时拥有part属性和disabled(或明确未禁用)属性的元素,比如:

<td role="gridcell" part="date" tabindex="-1" aria-label="1 Czerwiec 2024, sobota">1</td>

示例中,禁用状态的按钮本应通过.app-1::part(button-1):disabled将文本设为橙色,但该选择器无效;而.app-1::part(label-1):hover能正常作用于标签:

let template = document.querySelector('.temp-1').innerHTML;
let shadowElement = document.querySelector('.app-1');
let shadow = shadowElement.attachShadow({ mode: 'open' });
shadow.innerHTML = template;
<template class="temp-1">
  <div part="label-1">
    Label encapsulated in Shadow DOM
  </div>
  <button part="button-1" disabled>
    Click me!
  </button>
</template>
<style>
  .app-1 { color: green; background-color: lightblue; }
  .app-1::part(label-1):hover { color: orange; }
  .app-1::part(button-1) { color: lime; }
  .app-1::part(button-1):disabled { color: orange; }
</style>
<div class="app-1"></div>
替代方案

1. Shadow DOM内部编写状态样式

直接在Shadow Root内部的样式中针对元素状态编写规则,完全规避外部选择器的兼容性问题,这也是最符合Shadow DOM封装逻辑的方案:

<template class="temp-1">
  <style>
    [part="button-1"]:disabled {
      color: orange;
    }
  </style>
  <div part="label-1">
    Label encapsulated in Shadow DOM
  </div>
  <button part="button-1" disabled>
    Click me!
  </button>
</template>

2. 给元素添加带状态的part名称

如果必须从外部控制样式,可以给元素设置包含状态信息的part属性(支持多值),然后在外部通过组合part名称选择:

<template class="temp-1">
  <div part="label-1">
    Label encapsulated in Shadow DOM
  </div>
  <button part="button-1 disabled" disabled>
    Click me!
  </button>
</template>
<style>
  .app-1::part(button-1 disabled) {
    color: orange;
  }
</style>

若状态是动态变化的,需用JS监听状态变更并更新part属性:

const button = shadow.querySelector('[part="button-1"]');
// 监听禁用状态变化(示例逻辑,可根据实际场景调整)
button.addEventListener('disabledchange', () => {
  button.part.toggle('disabled', button.disabled);
});

3. 利用宿主元素状态传递样式

如果自定义元素本身带有disabled属性,可以通过:host()伪类在Shadow内部关联元素样式,同时保留part属性供外部扩展:

<template class="temp-1">
  <style>
    :host(:disabled) [part="button-1"] {
      color: orange;
    }
  </style>
  <div part="label-1">
    Label encapsulated in Shadow DOM
  </div>
  <button part="button-1" disabled>
    Click me!
  </button>
</template>

然后给宿主元素.app-1添加disabled属性,即可触发内部样式生效。

内容的提问来源于stack exchange,提问作者Arkadiusz Górecki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:23:21