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

悬停效果问题:盒子内文本随盒子变暗,需保持高亮

问题描述

我正在开发一个React组件,其中盒子会在悬停时变暗(通过opacity和filter调整),但我希望盒子内的文本无论悬停效果如何都保持完全高亮。

当前代码

Component.jsx

import React from 'react';
import { useNavigate } from 'react-router-dom';
import './BigBoxContainer.css';

export default function BigBoxContainer(props) {
    const navigate = useNavigate();

    const handleClick = () => {
        navigate('/');
    };

    return (
        <button className='big-tarot-box' style={{ backgroundImage: `url(${props.img})`}} onClick={handleClick}>
            <div className='box-body'>
                <h3>{props.title}</h3>
                <p>{props.description}</p>
            </div>
            <div className='text-overlay'>
                {props.overlayText}
            </div>
        </button>
    );
}

Component.css

.big-tarot-box {
  width: 400px;
  height: 400px;
  background-color: #ffffff;
  border: 2px solid #000000;
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  background-size: cover;
  background-position: center;
  transition: filter 0.8s ease, opacity 0.8s ease;
}

.big-tarot-box:hover {
  opacity: 0.7;
  filter: brightness(0.2);
  cursor: pointer;
}

.text-overlay {
  opacity: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 50px;
  font-weight: bold;
  color: white;
  transition: opacity 0.5s ease;
  z-index: 1;
}

.big-tarot-box:hover .text-overlay {
  opacity: 1;
}

.big-tarot-box {
  position: relative;
}

.big-tarot-box::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  transition: opacity 0.8s ease;
  opacity: 0;
  border-radius: 10px;
}

.big-tarot-box:hover::before {
  opacity: 1;
}

预期行为

盒子悬停时变暗,但内部文本保持完全高亮。

当前行为

盒子悬停时,内部文本也随之变暗,不符合预期。

尝试过的方法

调整悬停时的文本颜色,但没有效果。


解决方案

问题核心是你直接给父元素<button>添加了opacity和filter属性,这两个属性会被子元素继承,导致文本同步变暗。要解决这个问题,需将背景层与文本层彻底分离,让变暗效果仅作用于背景。

修改后的Component.jsx

把背景图单独放在子容器中,文本层独立于背景层:

import React from 'react';
import { useNavigate } from 'react-router-dom';
import './BigBoxContainer.css';

export default function BigBoxContainer(props) {
    const navigate = useNavigate();

    const handleClick = () => {
        navigate('/');
    };

    return (
        <button className='big-tarot-box' onClick={handleClick}>
            {/* 独立背景层,仅该层受悬停效果影响 */}
            <div className='box-background' style={{ backgroundImage: `url(${props.img})`}}></div>
            {/* 文本层,不受背景变暗影响 */}
            <div className='box-body'>
                <h3>{props.title}</h3>
                <p>{props.description}</p>
            </div>
            <div className='text-overlay'>
                {props.overlayText}
            </div>
        </button>
    );
}

修改后的Component.css

移除父元素的opacity和filter,将变暗效果转移到背景层,同时确保文本层级高于背景:

.big-tarot-box {
  width: 400px;
  height: 400px;
  border: 2px solid #000000;
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  cursor: pointer;
  background: transparent;
  padding: 0;
  border: none;
}

/* 背景层单独处理悬停变暗 */
.box-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #ffffff;
  background-size: cover;
  background-position: center;
  transition: filter 0.8s ease, opacity 0.8s ease;
  z-index: 0;
}

.big-tarot-box:hover .box-background {
  opacity: 0.7;
  filter: brightness(0.2);
}

.text-overlay {
  opacity: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 50px;
  font-weight: bold;
  color: white;
  transition: opacity 0.5s ease;
  z-index: 2;
}

.big-tarot-box:hover .text-overlay {
  opacity: 1;
}

.box-body {
  position: relative;
  z-index: 2;
  padding: 20px;
  color: white; /* 根据需求调整默认文本颜色 */
}

.big-tarot-box::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  transition: opacity 0.8s ease;
  opacity: 0;
  border-radius: 10px;
  z-index: 1;
}

.big-tarot-box:hover::before {
  opacity: 1;
}

关键说明

  1. 将背景图放入独立子元素.box-background,悬停时仅对该元素应用opacity和filter,避免影响文本。
  2. 所有文本元素(.box-body、.text-overlay)设置更高的z-index,确保它们在背景层和遮罩层之上。
  3. 重置按钮默认样式(padding:0、border:none),避免父元素样式与背景层冲突。

内容的提问来源于stack exchange,提问作者DragonFruit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:24:37