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

如何让React实现的Toggle Switch切换开关具备响应式特性?

响应式React Toggle Switch实现方案

核心优化思路

  • 移除容器固定宽高,让组件根据内部文本自动适配宽度,用padding控制高度
  • 简化组件结构,避免重复渲染相同内容,通过单个遮罩层实现切换效果
  • 用CSS类管理切换状态,替代内联样式的clipPath,提升可维护性
  • 添加移动端响应式适配,调整字体和间距保证小屏幕体验

修改后的React组件代码

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

export default function ToggleSwitch({ choice1, choice2 }) {
  const [isChoice1Active, setIsChoice1Active] = useState(false);

  const handleClick = () => {
    setIsChoice1Active(prev => !prev);
  };

  return (
    <div className={styles.container} onClick={handleClick}>
      {/* 底层文本容器 */}
      <div className={styles.labelsContainer}>
        <span className={styles.label}>{choice2}</span>
        <span className={styles.label}>{choice1}</span>
      </div>
      {/* 激活状态遮罩 */}
      <div 
        className={`${styles.activeMask} ${isChoice1Active ? styles.shiftLeft : styles.shiftRight}`}
        style={{
          backgroundColor: isChoice1Active ? "#eb9b30" : "#1464cf"
        }}
      >
        <span className={styles.activeLabel}>{isChoice1Active ? choice1 : choice2}</span>
      </div>
    </div>
  );
}

修改后的CSS代码

@import url("https://fonts.googleapis.com/css?family=Asap:400,500,700");

.container {
  position: relative;
  display: inline-flex;
  border-radius: 0.5rem;
  overflow: hidden;
  user-select: none;
  cursor: pointer;
  font-family: "Asap", sans-serif;
  padding: 0.5rem 0;
  border: 2px solid #e9e9e9;
}

.labelsContainer {
  display: flex;
  width: 100%;
}

.label {
  flex: 1;
  text-align: center;
  padding: 0 1rem;
  text-transform: uppercase;
  font-size: 0.8em;
  letter-spacing: 0.1em;
  color: #a9a9a9;
}

.activeMask {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.3s cubic-bezier(0, 0, 0, 1);
  color: white;
}

.activeLabel {
  text-transform: uppercase;
  font-size: 0.8em;
  letter-spacing: 0.1em;
}

.shiftLeft {
  transform: translateX(100%);
}

.shiftRight {
  transform: translateX(0);
}

/* 移动端响应式适配 */
@media (max-width: 480px) {
  .label,
  .activeLabel {
    font-size: 0.7em;
    letter-spacing: 0.05em;
    padding: 0 0.75rem;
  }

  .container {
    padding: 0.4rem 0;
  }
}

关键优化点说明

  1. 自适应尺寸:容器使用inline-flex,宽度由内部文本和padding自动撑开,完美适配不同长度的选项文本
  2. 结构简化:仅保留底层文本容器和单个遮罩层,避免重复渲染,减少DOM节点数量
  3. 状态逻辑简化:用布尔值isChoice1Active管理激活状态,逻辑更直观,降低出错概率
  4. 响应式适配:通过媒体查询针对小屏幕调整字体大小和内边距,保证移动端交互体验
  5. 样式可维护性:用CSS类控制遮罩位移,替代内联clipPath,后续修改样式只需调整CSS即可

内容的提问来源于stack exchange,提问作者shestakov-dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:45:47