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

添加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&nbsp;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&nbsp;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也无法突破父层的层级限制,导致视频覆盖在可交互内容上方。

调整步骤:

  1. 移除父容器的-z-10类,避免整个容器被压到底层
  2. 给背景视频设置更低的z-index(比如z-[-1]),确保它在所有内容下方
  3. 保留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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:45:39