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

基于JSX的两列响应式布局转纯CSS实现方案咨询

问题描述

我已实现一个基于JSX的两列响应式布局,但对JavaScript实现的方式不满意,想改用纯CSS方案,核心原因是要给布局添加动画效果。以下是我需要的响应式效果的JSX结构和布局截图,想知道需要给SplitContent、SplitContentLeft、SplitContentRight应用哪些CSS来实现该效果。

JSX结构

<SplitContent>
  <SplitContentLeft>First</SplitContentLeft>
  <SplitContentRight>Second</SplitContentRight>
  <SplitContentRight>Third</SplitContentRight>
  <SplitContentLeft>Fourth</SplitContentLeft>
  <SplitContentLeft>Fifth</SplitContentLeft>
</SplitContent>

布局效果

移动端布局

移动端布局

桌面端布局

桌面端布局

补充说明

附上用TypeScript将元素分类到各自数组的原实现代码,子组件仅为无样式的div:

import { twMerge } from "tailwind-merge";
import React from "react";
import { SplitContentLeft } from "./SplitContentLeft";
import { SplitContentRight } from "./SplitContentRight";

export type SplitContentProps = React.ComponentPropsWithoutRef<"div">;

export const SplitContent: React.FC<SplitContentProps> = ({
  className,
  children,
  ...props
}) => {
  const leftChildren: React.ReactElement[] = [];
  const rightChildren: React.ReactElement[] = [];

  React.Children.forEach(children, (child) => {
    if (React.isValidElement(child)) {
      if (child.type === SplitContentLeft) {
        leftChildren.push(child);
        return;
      }
      if (child.type === SplitContentRight) {
        rightChildren.push(child);
        return;
      }
    }
  });

  return (
    <div
      className={twMerge("flex w-full gap-4 sm:gap-6", className)}
      {...props}
    >
      <div className="flex w-full flex-col gap-4 sm:hidden">{children}</div>
      <div className="hidden w-full flex-col gap-6 sm:flex sm:justify-center">
        {leftChildren}
      </div>
      <div className="hidden w-full flex-col gap-6 sm:flex sm:justify-center">
        {rightChildren}
      </div>
    </div>
  );
};

纯CSS解决方案

利用CSS Grid的自动布局能力结合媒体查询,无需JS拆分元素即可实现需求,同时完美支持动画效果。以下是各组件的CSS样式及调整后的React组件代码:

1. 核心CSS样式

/* SplitContent 容器 */
.split-content {
  /* 移动端:垂直堆叠,间距对应原gap-4 */
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 100%;
}

/* 桌面端断点(示例用768px,可按需调整) */
@media (min-width: 768px) {
  .split-content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem; /* 对应原sm:gap-6 */
  }

  /* 强制左侧元素归到第一列 */
  .split-content-left {
    grid-column: 1;
  }

  /* 强制右侧元素归到第二列 */
  .split-content-right {
    grid-column: 2;
  }
}

/* SplitContentLeft/SplitContentRight 基础样式 */
.split-content-left,
.split-content-right {
  padding: 1rem;
  border-radius: 0.5rem;
  /* 添加过渡动画,支持布局变化时的平滑过渡 */
  transition: all 0.3s ease;
}

/* 可选:交互动画示例 */
.split-content-left:hover,
.split-content-right:hover {
  transform: translateY(-4px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

2. 调整后的React组件(移除JS拆分逻辑)

import { twMerge } from "tailwind-merge";
import React from "react";

export type SplitContentProps = React.ComponentPropsWithoutRef<"div">;

export const SplitContent: React.FC<SplitContentProps> = ({
  className,
  children,
  ...props
}) => {
  return (
    <div
      className={twMerge("split-content", className)}
      {...props}
    >
      {children}
    </div>
  );
};

// SplitContentLeft 组件
export const SplitContentLeft: React.FC<React.ComponentPropsWithoutRef<"div">> = ({
  className,
  children,
  ...props
}) => {
  return (
    <div className={twMerge("split-content-left", className)} {...props}>
      {children}
    </div>
  );
};

// SplitContentRight 组件
export const SplitContentRight: React.FC<React.ComponentPropsWithoutRef<"div">> = ({
  className,
  children,
  ...props
}) => {
  return (
    <div className={twMerge("split-content-right", className)} {...props}>
      {children}
    </div>
  );
};

方案说明

  • 移动端:采用Flex垂直堆叠所有元素,保留原有的DOM顺序和间距。
  • 桌面端:切换为Grid布局,通过grid-column属性自动将左右元素分组到对应列,无需JS处理子元素分类。
  • 动画支持:通过transition属性为元素添加过渡效果,布局切换、交互操作时均能实现平滑动画。
  • 可扩展性:断点、间距、动画参数均可灵活调整,适配不同设计需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:05:31