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

如何在CSS中实现标签页间的平滑弧形过渡效果?

问题:标签页活跃标签与下一个标签间的平滑弧形过渡实现

我正在开发一个基于React和Tailwind的标签页组件,想要实现活跃标签与下一个标签之间的平滑弧形过渡效果,尝试用CSS伪元素但没达到预期。

当前效果

当前效果截图

实际代码

React组件代码

import { useState } from "react";
import FAQCollapsible from "./FAQCollapsible";
import "./styles.css";

// 省略tabs数据定义...

const FAQTabs = () => {
  const [activeTab, setActiveTab] = useState(tabs[0]);

  const handleTabClick = (tab) => {
    setActiveTab(tab);
  };

  return (
    <div className="my-[80px] mx-auto mx-full md:my-0 md:py-[80px] md:px-[196px]">
      <div
        className="md:max-w-[768px] mx-auto border top-left-border-rad-none border-purple rounded-[20px]"
      >
        <div
          data-tab-labels-container
          className="flex justify-start bg-white -mt-[7.75%] rel-1px"
        >
          {tabs.map((tab, index) => {
            const isActive = activeTab === tab;
            const isNextTab =
              tabs[(tabs.indexOf(activeTab) + 1) % tabs.length] === tab;
            const nextTabClass =
              isNextTab && index !== 0 ? "next-tab-border-radius" : "";

            return (
              <button
                style={{ fontFamily: "Clash Display" }}
                key={tab}
                className={`px-[1rem] py-[13px] md:px-14 md:py-4 text-center tabs-border text-sm md:text-[18px] leading-[140%] border-rad-top ${
                  isActive
                    ? "bg-white negative-fff-border text-black font-semibold special-class"
                    : isNextTab
                    ? `bg-[#A05BF7] text-white font-medium border-none ${nextTabClass}`
                    : "bg-purple text-white font-medium border-none"
                }`}
                onClick={() => handleTabClick(tab)}
              >
                {tab}
              </button>
            );
          })}
        </div>
        {/* 折叠面板区域 */}
      </div>
    </div>
  );
};

export default FAQTabs;

自定义CSS

.negative-fff-border {
  position: relative;
}
.negative-fff-border::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 10px;
  bottom: -5px;
  background: #fff;
  bottom: -8%;
  left: 0;
}
.top-left-border-rad-none {
  border-top-left-radius: 0px !important;
}
.next-tab-border-radius {
  border-bottom-left-radius: 20px;
}
.tabs-border {
  border-top: 1px solid #7c1be0;
  border-left: 1px solid #7c1be0;
  border-right: 1px solid #7c1be0;
}
.rel-1px {
  position: relative;
  right: 1px;
}
.border-rad-top {
  border-top-right-radius: 20px;
  border-top-left-radius: 20px;
}
.next-to-active {
  background: #a05bf7;
}
.special-class {
  position: relative;
}
.special-class::after {
  content: "";
  position: absolute;
  width: 22px; 
  height: 20px; 
  background: #fff; 
  bottom: -11px; 
  left: calc(100% - 10px); 
  border-bottom-left-radius: 20px; 
  transform: rotate(45deg); 
  z-index: 1; 
}

期望效果

期望效果截图


解决方案

核心思路

放弃旋转伪元素的方式,改用两个对称伪元素组合:用白色弧形覆盖活跃标签右侧,同时给下一个标签左侧设置匹配的弧形,通过背景色衔接实现平滑过渡。

步骤1:修改活跃标签的伪元素

替换.special-class::after的样式,去掉旋转,改成纯弧形:

.special-class {
  position: relative;
  overflow: hidden; /* 避免伪元素超出标签范围 */
}
.special-class::after {
  content: "";
  position: absolute;
  width: 40px;
  height: 40px;
  background: #fff;
  bottom: 0;
  right: -20px; /* 偏移一半,让弧形一半在标签外 */
  border-bottom-left-radius: 100%; /* 生成左下弧形 */
  z-index: 1;
}

步骤2:优化下一个标签的样式

给下一个标签添加左侧弧形,匹配活跃标签的弧度:

.next-tab-border-radius {
  border-bottom-left-radius: 20px;
  position: relative;
  overflow: hidden;
}
.next-tab-border-radius::before {
  content: "";
  position: absolute;
  width: 40px;
  height: 40px;
  background: #A05BF7; /* 和标签背景色一致 */
  bottom: 0;
  left: -20px;
  border-bottom-right-radius: 100%; /* 生成右下弧形 */
  z-index: 0;
}

步骤3:调整布局细节

  1. 移除.rel-1px的right: 1px,避免布局偏移
  2. 修改.negative-fff-border::after,确保底部白色条和弧形衔接:
.negative-fff-border::after {
  content: "";
  position: absolute;
  width: calc(100% - 20px); /* 减去弧形覆盖的宽度 */
  height: 10px;
  bottom: -8%;
  left: 0;
  background: #fff;
  z-index: 2;
}

步骤4:简化React组件的类名判断

去掉index !== 0的条件,直接给下一个标签应用类名:

const nextTabClass = isNextTab ? "next-tab-border-radius" : "";

通过以上调整,两个对称的弧形会自然衔接,实现设计图中的平滑过渡效果,同时避免旋转伪元素带来的角度错位问题。


内容的提问来源于stack exchange,提问作者Tomas Gil Amoedo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:36:07