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

求助:Tailwind CSS实现项目详情面板右侧平滑滑入滑出

问题根源与修复方案

核心问题

你当前代码通过{selectedProject !== null && (...)}做条件渲染,关闭详情时组件直接被卸载,根本没机会执行translate-x-full的退出过渡动画。菜单栏的问题同理——条件渲染导致组件销毁,过渡效果无法触发。

修复步骤

  1. 始终渲染详情面板,通过类控制位置和可见性,而非条件渲染移除组件
  2. 搭配opacity和pointer-events属性,确保滑出后组件不遮挡底层内容
  3. 调整过渡类,保证位移和透明度变化都能触发平滑动画

修改后的完整代码

<div
  className={`fixed top-0 right-0 w-full h-full md:w-1/2 z-20 bg-white px-5 py-10 overflow-scroll transform transition-all duration-600 ${
    selectedProject !== null ? 'translate-x-0 opacity-100 pointer-events-auto' : 'translate-x-full opacity-0 pointer-events-none'
  }`}
>
  <div
    className="flex items-center justify-between w-full px-1 py-2"
    onClick={closeDetails}
  >
    <div>
      <Image
        src={back}
        alt={back}
        quality={100}
        height={30}
        width={30}
        placeholder="blur"
        className="cursor-pointer"
      />
    </div>
    <Link href="#projects">
      <div onClick={closeDetails} className="font-bold cursor-pointer">
        Back to projects
      </div>
    </Link>
  </div>
  <hr className="pb-10" />
  <p className="text-lg font-extrabold text-black pb-1">
    {selectedProject !== null ? projects[selectedProject].name : ''}
  </p>
  <p className="text-gray-700  text-base pb-4 ">
    {selectedProject !== null ? projects[selectedProject].details : ''}
  </p>
  {selectedProject !== null && (
    <Image
      src={projects[selectedProject].image}
      alt={`${projects[selectedProject].name} screenshot`}
      quality={100}
      placeholder="blur"
      blurDataURL="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOMzoyuBwAD5gGgL5NkuQAAAABJRU5ErkJggg=="
      className="h-72 md:h-80 max-w-auto rounded-lg"
    />
  )}
  <p className="text-base font-bold text-black pb-1 pt-7">About</p>
  <p className="text-xs md:text-base">
    {selectedProject !== null ? projects[selectedProject].details : ''}
  </p>
  <p className="text-base font-bold text-black pb-1 pt-7">
    Technologies
  </p>
  {selectedProject !== null && (
    <div className="mt-5">
      <div className="flex flex-wrap gap-3 mt-3">
        {projects[selectedProject].skills.map((skill, skillIndex) => (
          <span
            key={skillIndex}
            className="w-fit inline-flex items-center rounded-md bg-indigo-50 px-2 py-1 text-sm font-medium text-black ring-1 ring-inset ring-indigo-700/10"
          >
            {skill}
          </span>
        ))}
      </div>
    </div>
  )}
  <div className="w-fit gap-1 flex items-center">
    <Image
      src={earth}
      alt="earth icon"
      quality={100}
      height={20}
      width={20}
      placeholder="blur"
      className="cursor-pointer"
    />
    <p className="text-base font-bold text-black pb-1 pt-7">Website</p>
  </div>
  {selectedProject !== null && (
    <Link href={projects[selectedProject].link}>
      {projects[selectedProject].link}
    </Link>
  )}
  <div className="w-fit gap-3 flex items-center">
    <Image
      src={github}
      alt="github icon"
      quality={100}
      height={20}
      width={20}
      placeholder="blur"
      className="cursor-pointer"
    />
    <p className="text-base font-bold text-black pb-1 pt-7">Github</p>{' '}
  </div>
  {selectedProject !== null && (
    <Link href={projects[selectedProject].github}>
      {projects[selectedProject].github}
    </Link>
  )}
</div>

关键改动说明

  • 移除外层条件渲染,始终保留详情容器在DOM中
  • 新增opacity和pointer-events属性,解决滑出后组件遮挡底层点击事件的问题
  • 将transition改为transition-all,确保位移和透明度变化都能触发过渡
  • 内部动态内容(如图片、链接)保留条件渲染,避免selectedProject为null时出现报错

菜单栏通用修复思路

和详情面板逻辑完全一致:

  • 不要用条件渲染卸载菜单栏组件
  • 右侧菜单用translate-x-full,左侧菜单用translate-x-[-100%],配合opacity和pointer-events控制显示状态
  • 确保组件始终存在于DOM中,仅通过类名变化触发过渡动画

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:52:12