添加sticky实现视差效果后,页面内容无法hover及点击的问题
问题:背景视频视差效果与内容交互冲突
我制作了一个带背景视频的页面,想要实现视差效果(对应代码中标记// this sticky is the problem的sticky类)。添加sticky类后,视差效果正常生效,但背景视频会显示在内容前方,导致按钮、导航等内容无法悬停和点击;移除sticky类后,视差效果消失,但按钮等内容可正常交互。
代码如下:
import React, { useRef, useState, useContext, useCallback } from 'react'; import Image from 'next/image'; import { IoIosArrowDown, } from 'react-icons/io'; import { MdKeyboardArrowDown } from 'react-icons/md'; import { ScrollContext } from '../utils/scroll-observer'; import s from '../styles/masthead.module.css'; const Masthead: React.FC = () => { const [imageLoaded, setImageLoaded] = useState(false); const mastheadRef = useRef<HTMLDivElement>(null); const { scrollY } = useContext(ScrollContext); let progress = 0 const { current: elContainer } = mastheadRef; if (elContainer) { progress = Math.min(1, scrollY / elContainer.clientHeight); } const scrollDown = () => { // scroll down 100 vh window.scrollTo({ top: window.innerHeight, behavior: 'smooth', }); } const textStyle = ' font-light w-[50%] md:2xl lg:text-3xl xl:text-4xl mx-3 drop-shadow-[0_5px_3px_rgba(0,0,0,0.2)] border-b-2 border-transparent'; const bottomBorder = 'hover:border-b-2 hover:border-gray-200' const animate = '' const topItem = textStyle + bottomBorder + animate; return ( <div ref={mastheadRef} className='min-h-screen flex flex-col justify-between top-0 -z-10 sticky' // this sticky is the problem style={{ transform: `translateY(${-progress * 20}vh)` }} > <video autoPlay loop muted playsInline className='absolute w-full h-full top-0 left-0 object-cover z-0 overflow-hidden' > <source src='/assets/video/background.mp4' type='video/mp4; codecs=hvc1' /> <source src='/assets/video/background.webm' type='video/webm; codecs=vp9' /> </video> <div className='p-12 z-20 text-white relative'> <div className='flex flex-row flex-grow-0 justify-between'> <h1 className='text-8xl xl:text-9xl font-bold drop-shadow-[0_5px_3px_rgba(0,0,0,0.4)]'>Qudak</h1> <div className='flex flex-row items-center'> <h2 className={topItem}>Produkten</h2> <h2 className={topItem}>Kontakt</h2> <div className={topItem} onClick={scrollDown}> <h2 >Om Oss</h2> </div> <button className={`bg-slate-700 text-white items-center font-light !text-2xl !xl:text-3xl rounded-full px-2 py-1 mx-3 drop-shadow-[0_5px_3px_rgba(0,0,0,0.2)] ${textStyle}`} > Boka Demo </button> <h2></h2> </div> </div> </div> <div className='p-12 flex flex-row justify-between z-10 text-white transition-all duration-1000'> <h2 className='flex items-center text-center font-medium z-10 text-white drop-shadow-[0_5px_3px_rgba(0,0,0,0.4)] text-2xl xl:text-3xl'> Industriella lösningar, på rätt sätt! </h2> <p></p> <div className='justify-between'> <div onClick={scrollDown} className='flex flex-row items-center justify-center cursor-pointer'> <MdKeyboardArrowDown size={70} /> </div> </div> </div> </div > ); } export default Masthead;
解决方案
问题根源在于父容器的z-index: -10,这个属性会让整个容器(包括内部所有内容)都处于页面底层,即使子元素设置了z-20也无法突破父层的层级限制,导致视频覆盖在可交互内容上方。
调整步骤:
- 移除父容器的
-z-10类,避免整个容器被压到底层 - 给背景视频设置更低的z-index(比如
z-[-1]),确保它在所有内容下方 - 保留
sticky类维持视差效果
修改后的核心代码片段:
<div ref={mastheadRef} className='min-h-screen flex flex-col justify-between top-0 sticky' // 移除-z-10 style={{ transform: `translateY(${-progress * 20}vh)` }} > <video autoPlay loop muted playsInline className='absolute w-full h-full top-0 left-0 object-cover z-[-1] overflow-hidden' // 设置z-index为-1 > <source src='/assets/video/background.mp4' type='video/mp4; codecs=hvc1' /> <source src='/assets/video/background.webm' type='video/webm; codecs=vp9' /> </video> {/* 下方内容保持不变 */} </div>
原理说明
- 父容器不再设置负z-index,子元素的z-index可以正常生效,可交互内容的层级自然高于视频
- 视频的z-index设为-1,只会被默认z-index为0的元素覆盖,不会影响页面其他元素的层级关系
sticky属性保留,配合translateY变换,视差效果可以正常工作
内容的提问来源于stack exchange,提问作者Olle Jernström
相关产品推荐
相关产品推荐

