HTML元素::after伪元素不显示:剧院选座hover弹窗实现问题
问题原因与解决方案
核心问题:<img> 是替换元素(内容由外部资源替换的元素),浏览器不会为这类元素生成 ::before/::after 伪元素,所以你写的 seat::after 根本不会被渲染。
修复方案:用容器包裹图片
把每个座位图片放在一个容器 <div> 里,给容器添加 seat 类,伪元素就可以作用在容器上了。
修改后的代码:
JavaScript
function createSeats(pattern, rows) { const seatsContainer = document.getElementById("seats"); for (let i = 0; i < rows; i++) { for (let j = 0; j < pattern.length; j++) { const seatType = pattern[j] % 2 === 0 ? "seat" : "nothing"; for (let k = 0; k < pattern[j]; k++) { // 创建容器div const seatContainer = document.createElement("div"); seatContainer.classList.add(seatType); // 可添加自定义属性存储座位信息,用于弹窗展示 seatContainer.dataset.row = i + 1; seatContainer.dataset.seat = k + 1; const seatImg = document.createElement("img"); seatImg.src = `./images/${seatType}.png`; seatImg.alt = seatType; seatContainer.appendChild(seatImg); seatsContainer.appendChild(seatContainer); } } } } createSeats([10, 1, 10], 13);
CSS
* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Roboto', sans-serif; background-color: #f5f5f5; height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; flex-direction: column; } h1 { margin-bottom: 1rem; } #frame { height: 50vh; width: 50vw; background-color: white; display: flex; justify-content: center; align-items: center; flex-direction: column; } #stage { border-radius: 0 0 50% 50%; border: 1px solid black; height: 10%; width: 100%; text-align: center; } #seats { --rows: 13; --columns: 21; display: grid; background-color: antiquewhite; grid-template-columns: repeat(var(--columns), calc(100% / var(--columns))); grid-template-rows: repeat(var(--rows), var(--columns)); width: 100%; height: 90%; margin-top: 1rem; overflow-y: scroll; } /* seat类作用在容器上 */ .seat { position: relative; /* 让伪元素相对容器定位 */ width: 100%; aspect-ratio: 1/1; cursor: pointer; } .seat img { transform: rotate(180deg); width: 100%; height: 100%; } .seat.occupied { cursor: not-allowed; opacity: 0.3; } .seat::after { /* 读取自定义属性显示真实座位信息 */ content: 'Row ' attr(data-row) ', Seat ' attr(data-seat); position: absolute; bottom: 110%; left: 50%; transform: translateX(-50%); background: #333; color: white; padding: 4px 8px; border-radius: 4px; font-size: 12px; white-space: nowrap; display: none; z-index: 10; } .seat:hover::after { display: block; } .nothing { height: 100%; width: 100%; }
HTML(无需修改)
<h1>Sitzplatz</h1> <section id="frame"> <div id="stage">Bühne</div> <div id="seats"></div> </section>
额外说明
- 给容器加
position: relative,配合伪元素的position: absolute可以精准控制弹窗位置,避免打乱原有布局 - 通过自定义属性
data-row、data-seat存储座位信息,用attr()方法在伪元素中读取,实现真实座位信息展示 - 调整弹窗的
bottom值和样式,让弹窗更贴合交互需求
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

