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

如何使用CSS匹配动态生成日期类名的首个同日期元素

问题场景

你当前需要处理按日期升序排列的事件列表,生成DOM时会给每个事件的日期节点拼接格式为event_date_dd-mm-yyyy的动态类名,DOM结构示例如下:

<div class="event">
 <div class="event_date_20-06-2020">title</div>
</div>
<div class="event">
 <div class="event_date_20-06-2020">title</div>
</div>
<div class="event">
 <div class="event_date_21-06-2020">title</div>
</div>
<div class="event">
 <div class="event_date_22-06-2020">title</div>
</div>
<div class="event">
 <div class="event_date_22-06-2020">title</div>
</div>

需求是仅展示每个日期对应的第一个事件,你之前尝试的通配类CSS规则没有生效,失效代码如下:

.event_date_[all-dates] {display:none;}
.event_date_[first-iteration-of-a-date]:first-of-type {display:block;}
原因说明

你之前的写法无法生效有两个核心原因:

  • CSS本身不支持[all-dates]这类占位符通配语法,属性选择器只能匹配固定的属性值片段
  • :first-of-type是按标签类型匹配同级第一个元素,无法实现「按动态类名分组取第一个」的效果

纯CSS没有提供直接匹配「拥有相同类名片段的第一个元素」的选择器,推荐按优先级选以下方案实现:


可行方案

方案1:渲染层加标记类(推荐,无兼容问题、性能最优)

你本身是动态拼接生成DOM的,只需要在遍历事件列表生成结构时加一层判断:

  • 用变量记录上一个渲染的事件日期
  • 如果当前事件日期和上一个日期不一致,给当前外层.event节点追加一个固定标记类,比如first-of-date
  • 同日期的后续事件不加这个类

配套CSS非常简单:

/* 默认隐藏所有事件 */
.event {
  display: none;
}
/* 只显示每个日期组的第一个事件 */
.event.first-of-date {
  display: block;
}

这个方案不依赖「列表已按日期排序」的前提,兼容所有浏览器,是生产环境最优选择。

方案2:JS后置加标记(无需修改渲染逻辑)

如果已经生成了静态DOM、无法修改前端渲染/服务端渲染的拼接逻辑,可以用几行JS遍历节点,自动给每个日期组的第一个事件加标记类:

const appearedDate = new Set();
document.querySelectorAll('.event [class*="event_date_"]').forEach(dateNode => {
  // 提取当前节点上的完整日期类名
  const dateCls = Array.from(dateNode.classList).find(cls => cls.startsWith('event_date_'));
  if (!appearedDate.has(dateCls)) {
    appearedDate.add(dateCls);
    dateNode.closest('.event').classList.add('first-of-date');
  }
});

配套CSS和方案1完全一致即可。

方案3:纯CSS实现(不推荐,依赖高版本浏览器+严格DOM结构)

如果你的项目只需要兼容支持:has()选择器的现代浏览器(Chrome 105+、Firefox 121+、Safari 15.4+),且能保证事件列表严格按日期排序、同日期事件连续排列,可以用以下纯CSS规则实现,但不推荐生产环境使用,鲁棒性很差:

/* 默认隐藏所有日期节点 */
.event [class*="event_date_"] {
  display: none;
}
/* 第一个日期节点默认显示 */
.event:first-child [class*="event_date_"] {
  display: block;
}
/* 匹配相邻日期切换的第一个节点 */
.event:has(.event_date_20-06-2020) + .event:has(.event_date_21-06-2020) .event_date_21-06-2020,
.event:has(.event_date_21-06-2020) + .event:has(.event_date_22-06-2020) .event_date_22-06-2020 {
  display: block;
}

注意:这个写法依赖你提前枚举所有可能的日期值,无法真正做到动态通配,仅做原理演示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:27:17