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

如何实现点击旋转且旋转过程中切换内容的CSS卡片

解决卡片翻转时内容同步切换的问题

你的核心问题在于销毁重建卡片容器导致状态切换时机和动画脱节,同时ref被重复绑定到不同元素上引发逻辑混乱。下面是修复后的实现方案,能让内容在旋转到90度的瞬间切换,实现流畅的翻转效果:

核心改动思路

  • 保留同一个卡片容器,避免销毁重建,确保ref始终指向正确元素
  • 在动画进行到一半(旋转至90度时)切换内容,而非等动画结束
  • 用CSS 3D变换优化翻转视觉效果

修复后的React代码

import { useState, useRef } from 'react';

function FlipCard(props) {
  const [isCardTurned, setIsCardTurned] = useState(false);
  const cardContainerRef = useRef(null);
  const isAnimating = useRef(false); // 防止重复点击触发动画

  function turnCard() {
    if (isAnimating.current) return;
    isAnimating.current = true;

    // 第一步:开始旋转到90度
    cardContainerRef.current.style.transform = "rotateY(90deg)";

    // 动画进行到一半(500ms,对应总动画时长1s)时切换内容
    setTimeout(() => {
      setIsCardTurned(prev => !prev);
      // 第二步:从90度旋转回0度(此时内容已切换)
      cardContainerRef.current.style.transform = "rotateY(0deg)";
    }, 500);

    // 动画结束后重置可点击状态
    setTimeout(() => {
      isAnimating.current = false;
    }, 1000);
  }

  return (
    <div 
      className="cardContainer" 
      onClick={turnCard} 
      ref={cardContainerRef}
    >
      <CardHead 
        srcHead={props.srcHead} 
        projektTitel={props.projektTitel} 
        datumBegin={props.datumBegin} 
        datumEnd={props.datumEnd} 
      />
      {/* 正面内容 */}
      {!isCardTurned && (
        <div className="cardContent cardFace">
          <div className="cardImage">
            <img src={props.imageSrc} alt="项目缩略图" />
          </div>
          <div className="cardShortDescription">
            <div className="shortDescriptionText">
              {props.shortDescription}
            </div>
          </div>
        </div>
      )}
      {/* 反面内容 */}
      {isCardTurned && (
        <div className="cardLongDescription cardFace">
          <div className="cardLongDescriptionText">
            {props.longDescription}
          </div>
        </div>
      )}
    </div>
  );
}

优化后的CSS代码

.cardContainer {
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: rgb(199, 220, 248);
  transition: transform 1s ease; /* 统一动画时长和曲线 */
  transform-style: preserve-3d; /* 开启3D空间 */
  cursor: pointer;
}

.cardContainer:hover {
  box-shadow: 0px 0px 50px rgb(5, 48, 112);
}

/* 控制卡片正反内容的显示,确保切换时无闪烁 */
.cardFace {
  backface-visibility: hidden; /* 隐藏背面元素 */
  flex: 1;
  width: 100%;
}

关键细节说明

  1. 避免重复点击:用isAnimating ref标记动画状态,防止用户在动画未完成时重复点击导致逻辑混乱
  2. 动画时机控制:总动画时长1秒,在500ms时切换内容,此时卡片刚好旋转到90度(视觉上完全侧转),切换内容后继续旋转回0度,用户看不到内容切换的闪烁
  3. 3D变换优化:添加transform-style: preserve-3d和backface-visibility: hidden让翻转效果更贴近真实的3D卡片
  4. 统一容器:不再销毁重建卡片容器,ref始终指向同一个元素,避免DOM操作的额外开销和ref指向错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:52:50