必须用 JavaScript 维护选区坐标并结合 CSS Grid 显式轨道定位实现 Excel 式多单元格选中,纯 CSS 无法动态计算矩形边界、响应拖拽或键盘操作。

不能靠 position: sticky 或单纯 :hover 实现真正的多单元格选中高亮——Excel 那种拖拽式、跨行跨列、支持键盘扩展的交互,必须结合 JavaScript 记录选区 + CSS Grid 的显式轨道定位来驱动样式。
为什么纯 CSS 无法模拟 Excel 式选中
Excel 的选中不是“单个单元格 hover”,而是:一个矩形区域(起始单元格 + 结束单元格),可跨越任意行列,且需响应鼠标拖拽、Shift+方向键、Ctrl+点击等操作。CSS 本身没有「当前选区坐标」这个状态变量,:focus-within 或 :has() 也无法动态计算矩形边界。
-
:is()和:nth-child()只能匹配静态位置,无法响应运行时拖拽终点 -
grid-area是声明式布局属性,不能由用户交互实时重写 - 浏览器不提供「当前鼠标按下起点 → 移动路径覆盖哪些 grid cell」的原生 CSS 钩子
必须用 JS 维护选区坐标,再映射到 CSS 类
核心思路是:JS 监听 mousedown/mousemove/mouseup,算出起始行/列和结束行/列,生成类似 sel-r2c1-r5c3 的类名,加在 Grid 容器上;CSS 用属性选择器或类名批量匹配对应单元格。
- 每个单元格()必须带明确的
data-row和data-col属性,例如data-row="3" data-col="2"- Grid 容器(
.grid)在选中时动态添加类,如sel-r2c1-r5c3,表示从第2行第1列到第5行第3列- CSS 写法示例:
.grid.sel-r2c1-r5c3 .cell[data-row="3"][data-col="2] { background-color: #b3d9ff; }——但手动写所有组合不现实,应改用 JS 注入 style 标签或使用 CSS Custom Properties 动态控制避免滚动错位:单元格必须脱离文档流对齐
一旦加入选中高亮,如果还用原生
,
滚动时表头与内容列宽极易脱节,高亮色块会漂移。必须回归 Grid 固定列宽方案:- 放弃
,全部用
++- Grid 容器设
grid-template-columns: 120px 1fr 100px 80px(显式列宽,不可用auto-fit)- 每个
.cell必须设min-width: 0,否则长文本撑开整列,导致高亮区域宽度失准- 滚动容器(
.grid)设max-height: 400px; overflow-y: auto,且确保无父级transform或will-change干扰 stacking context最易被忽略的细节:键盘交互与焦点管理
只做鼠标拖拽不够——Excel 用户习惯用
Shift + ↓扩展选区、Ctrl + 点击多选非连续区域。这些必须由 JS 显式处理,并更新 DOM 中的aria-selected和tabindex:- 首次点击某单元格时,设
tabindex="0"并focus(),使其可键盘操作 - 按
Shift + 方向键时,不直接修改 DOM 类,而是更新 JS 中的selectionEnd坐标,再重新触发样式刷新 - 为无障碍考虑,每个
.cell应有role="gridcell",容器加role="grid"和aria-multiselectable="true"
- Grid 容器设
- Grid 容器(
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











