伪元素实现图片Hover阴影不显示问题排查求助
问题描述
我正在做一个学生项目,要实现可按需修改的数据仪表盘。在弹窗里,我尝试用CSS伪元素给图片加鼠标悬停阴影,但阴影没显示,求排查建议。相关代码如下:
HTML代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'> <title>Sail Vision</title> </head> <body> <div class="sidebar"> <div class="logo_content"> <div class="logo"> <i class='bx bx1-c-plus-plus'></i> <div class="logo_name">SailVision</div> </div> <i class='bx bx-menu' id="btn"></i> </div> <div class="menu-bar"> <ul class="dash_list"> <li> <a href="#"> <i class='bx bx-windows'></i> <span class="links_name">Dashboard n°1</span> </a> </li> <li> <a href="#"> <i class='bx bx-windows'></i> <span class="links_name">Dashboard n°2</span> </a> </li> <li> <a href="#"> <i class='bx bx-windows'></i> <span class="links_name">Dashboard n°3</span> </a> </li> <li> <a href="#"> <i class='bx bx-customize modal-trigger'></i> <span class="links_name">Template</span> </a> </li> </ul> <div class="bottom_content"> <li> <a href="#"> <i class='bx bx-cog'></i> <span class="links_name">Paramètre</span> </a> </li> </div> </div> </div> <div class="home"> <div class="template-1">Template n°1</div> </div> <div class="modal-container"> <div class="overlay"> <div class="template"> <div class="popup-header"> <button class="close-modal modal-trigger">X</button> <h1>Choix des templates</h1> </div> <div class="popup-body"> <ul class="temp-list"> <li> <a href="#"> <img src="Template1.png" alt="t1"> </a> </li> <li> <a href="#"> <img src="Template1.png" alt="t1"> </a> </li> <li> <a href="#"> <img src="Template1.png" alt="t1"> </a> </li> </ul> </div> </div> </div> </div> <script src="script.js"></script> </body> </html>
CSS代码
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); *{ font-family: 'Poppins', sans-serif; margin: 0; padding: 0; box-sizing: border-box } :root{ --body-color: #E4E9F7; --sidebar-color: #FFF; --primary-color: #1c1a1a; --primary-color-light: #F6F5FF; --toggle-color: #DDD; --text-color: #707070; --tran-02: all 0.2s ease; --tran-03: all 0.3s ease; --tran-04: all 0.4s ease; --tran-05: all 0.5s ease; } body{ height: 100vh; background: var(--body-color); } .sidebar{ position: fixed; top: 0; left: 0; height:100%; width: 78px; background: var(--primary-color); padding: 6px 14px; transition: all 0.5s ease; } .sidebar.active{ width: 240px } .sidebar .logo_content .logo{ color: #FFF; display: flex; height: 50px; width:100%; align-items: center; opacity: 0; pointer-events: none; } .sidebar.active .logo_content .logo{ opacity: 1; pointer-events: none; } .logo_content .logo i{ font-size: 28px; margin-right: 5px; } .logo_content .logo .logo_name{ font-size: 20px; font-weight: 400; } .sidebar #btn{ position: absolute; color: #FFF; top: 6px; left: 50%; font-size: 20px; height: 50px; width: 50px; text-align: center; line-height: 50px; cursor: pointer; transform: translateX(-50%); } .sidebar.active #btn{ left:90%; } .sidebar ul{ margin-top: 20px; } .sidebar li{ position: relative; height: 50px; width: 100%; margin: 0 0px; list-style: none; line-height:50px ; } .sidebar li a{ color: #FFF; display: flex; align-items: center; text-decoration: none; transition: all 0.4s ease; border-radius: 12px; white-space: nowrap; } .sidebar li a:hover{ color: #11101d; background: #FFF; } .sidebar li a i{ height: 50px; min-width: 50px; border-radius: 12px; line-height: 50px; text-align: center; } .sidebar .links_name{ opacity: 0; pointer-events: none; } .sidebar.active .links_name{ opacity: 1; pointer-events: auto; } .sidebar .menu-bar{ height: calc(100% - 50px); display: flex; flex-direction: column; justify-content: space-between; } .home{ position: relative; height: 100vh; left: 78px; width: calc(100% - 78px); background: var(--body-color); transition: var(--tran-05); } .home .text{ font-size: 30px; font-weight: 500; color: var(--text-color); padding: 8px 40px; } .sidebar.active ~ .home{ left: 240px; width: calc(100% - 78px); } .modal-container{ display: none; position: fixed; top: 0; width: 100vw; height: 100vh; flex-direction: column; } .modal-container.active{ display: flex; } .overlay{ position: absolute; width: 100%; height: 100%; background: #333333d3; } .template{ position: fixed; left: 50%; top: 50%; transform: translate(-50%,-50%); height: 300px; max-height: 720px; min-width: 520px; width: 45%; display: flex; flex-direction: column; } .popup-header{ width: 100%; height: 8.5%; border-radius: 2px; align-items: center; justify-content: space-between; padding: 0% 2%; background-color: #FFF; color: rgb(0, 0, 0); } .close-modal{ padding: 5px 20px; border: none; border-radius: 2px; font-size: 10px; position: absolute; top: 0px; right: 0px; cursor: pointer; background: #fff; color: rgb(0, 0, 0); } .close-modal:hover{ color: #FFF; background: rgb(188, 15, 15); } .popup-header h1{ font-size: 12px; margin-top: 5px; margin-left: 0px; font-family: Montserrat, sans-serif; font-weight: 500; } .popup-body{ height: 80%; padding: 2%; overflow-y: auto; background-color: #e0e0e0; } .modal-container .popup-body ul{ list-style: none; position: relative; height: 50px; width: 100%; margin: 0 10px; list-style: none; column-width: 200px; } .modal-container .popup-body ul li a img{ padding: 10px 10px; width: 175px; border-radius: 8px; background: #fff; cursor: pointer; box-shadow: 0 0 7px rgba(18,18,18,0.5); } .modal-container .popup-body ul li a img::after { content: ""; display: block; width: 100%; height: 100%; box-shadow: 0 0 25px rgba(18,18,18,0.8); opacity: 0; transition: opacity 0.3s ease-out; z-index: 1; } .modal-container .popup-body ul li a img:hover::after { opacity: 1; }
JS代码
const body = document.querySelector("body"), sidebar = body.querySelector(".sidebar"), btn = body.querySelector("#btn"); btn.addEventListener("click", () =>{ sidebar.classList.toggle("active"); }) const modalContainer = document.querySelector(".modal-container"); const modalTriggers = document.querySelectorAll(".modal-trigger"); modalTriggers.forEach(trigger => trigger.addEventListener("click",toggleModal)) function toggleModal(){ modalContainer.classList.toggle("active") }
错误原因排查
- img标签不支持伪元素:
<img>属于HTML替换元素,浏览器规范不允许为这类元素生成::before/::after伪元素,这是阴影不显示的核心原因。 - 伪元素定位缺失:即使忽略规范问题,你的伪元素没有设置
position: absolute,会和原图重叠且无法正确覆盖,z-index也无法发挥预期作用。
修复方案
方案1:用容器伪元素实现阴影(保留原有思路)
给每个图片套一个容器,通过容器的伪元素实现悬停阴影:
<!-- 修改HTML,给img加容器 --> <li> <a href="#"> <div class="img-wrapper"> <img src="Template1.png" alt="t1"> </div> </a> </li>
/* 修改CSS,用容器伪元素实现阴影 */ .modal-container .popup-body ul li a .img-wrapper { position: relative; display: inline-block; } .modal-container .popup-body ul li a .img-wrapper::after { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 8px; box-shadow: 0 0 25px rgba(18,18,18,0.8); opacity: 0; transition: opacity 0.3s ease-out; z-index: 1; pointer-events: none; } .modal-container .popup-body ul li a .img-wrapper:hover::after { opacity: 1; }
方案2:直接给图片加hover阴影(更简洁)
不需要伪元素,直接修改图片的hover样式:
.modal-container .popup-body ul li a img:hover { box-shadow: 0 0 25px rgba(18,18,18,0.8); transition: box-shadow 0.3s ease-out; }
内容的提问来源于stack exchange,提问作者Seji
相关产品推荐
相关产品推荐

