React组件z-index不生效求助:如何让.today元素显示在最上层
问题描述
我在React项目里碰到z-index不生效的问题:一个HTML组件被另一个遮挡,想通过z-index让目标元素(.today)显示在最上层。我已经给schedule-header设了z-index:1,schedule-body设了z-index:2,所有涉及的父元素也都加了position属性,但问题还是没解决,想知道我对z-index的理解哪里错了?
代码示例
HTML(React JSX)
<div className="schedule"> <div className="schedule-header"> Horaire | Semaine du {getFormattedDayNumber(monday)} {getFormattedMonth(monday, true)} </div> <div className="schedule-body"> <div className="schedule-days"> {Object.keys(days).map((day, index) => ( <div className="schedule-day"> <div className="day-header"> <span>{day} | {getFormattedDayNumber(getDateFromWeekMonday(monday, index))} {getFormattedMonth(getDateFromWeekMonday(monday, index))}</span> {day.toLowerCase() === getFormattedWeekday(today) ? <span className="today">Aujourd'hui</span> : null} </div> <div className="day-body"> {days[day].map(task => ( <TaskComponent task={task} pixelsPerHour={pixelsPerHour} /> ))} </div> </div> ))} </div> </div> </div>
CSS
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300;400&display=swap'); .schedule { position: relative; width: 100%; margin: 15px 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; border: 2px solid #f2f2f2; background-color: white; border-radius: 10px; padding: 0 10px; } .schedule-header { position: relative; width: 100%; font-size: 20px; font-family: 'Museo', sans-serif; font-weight: bold; padding: 10px 0 20px 20px; z-index: 1; } /* The arrow head */ .schedule-header::before { content: ""; display: block; border: 6px solid transparent; border-left-color: #f2f2f2; position: absolute; bottom: 5px; right: 13px; } /* The arrow line */ .schedule-header::after { content: ""; display: block; width: calc(100% - 20px); height: 2px; background-color: #f2f2f2; position: relative; top: 10px; } .schedule-body { position: relative; display: flex; width: 100%; margin-bottom: 5px; border-collapse: collapse; z-index: 2; } .schedule-days { position: relative; display: flex; flex-direction: row; width: 100%; } .schedule-day { position: relative; width: 100%; border-right: 2px solid #f2f2f2; overflow: hidden; } .schedule-day:first-child { border-left: 2px solid #f2f2f2; /* Ajoute une bordure à gauche pour le premier élément */ } .day-header { position: relative; font-weight: bold; font-family: 'Lato', sans-serif; font-size: 12px; width: 100%; height: 35px; text-align: center; border-bottom: 2px solid #f2f2f2; display: flex; align-items: center; justify-content: center; } .day-body p { margin: 2px 2px 0 2px; padding-left: 10px; padding-top: 5px; background-color: #6fe5eb; border-left: 5px solid #04B5CC; border-radius: 10px; } .today { position: absolute; transform: translateY(-20px); background: linear-gradient(to left, #04A9C4, #6FE5EB); padding: 3px 3px; border-radius: 5px; color: white; font-weight: 300; font-family: 'Lato', sans-serif; font-size: 12px; z-index: 9999; }
问题根源:你对z-index的两个核心误区
1. 层叠上下文的独立性
当你给schedule-header和schedule-body同时设置position: relative和z-index时,这两个元素各自创建了独立的层叠上下文。.today是schedule-body的后代元素,它的z-index值只在schedule-body的层叠上下文内部生效,完全无法突破到schedule-header的层叠上下文之上。哪怕你给.today设z-index:9999,它也只能在schedule-body内部的元素里排第一,没法跑到schedule-header的上层。
2. 父子元素的层级关系
schedule-body的z-index:2确实比schedule-header的z-index:1高,但这只是两个兄弟元素之间的层级对比。.today作为schedule-body的子元素,它的层叠层级是依附于schedule-body的,和schedule-header属于不同的层级分支,自然无法覆盖对方。
修复方案
方案1:移除父元素不必要的z-index
把schedule-header和schedule-body的z-index属性删掉,这样它们不会创建独立的层叠上下文,.today的z-index就能相对于共同父元素.schedule生效:
.schedule-header { position: relative; width: 100%; font-size: 20px; font-family: 'Museo', sans-serif; font-weight: bold; padding: 10px 0 20px 20px; /* 移除z-index:1 */ } .schedule-body { position: relative; display: flex; width: 100%; margin-bottom: 5px; border-collapse: collapse; /* 移除z-index:2 */ }
方案2:保持.today的定位设置
你已经给.today设置了position:absolute,这个是正确的——z-index只对static以外的定位元素生效,不需要改动。
现在.today的z-index:9999会相对于.schedule这个父层生效,就能顺利覆盖schedule-header了。
内容的提问来源于stack exchange,提问作者PandaaaPlays

