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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:47:52