css 两列响应式布局,其中列在JSX中指定

cclgggtu  于 2023-05-08  发布在  其他
关注(0)|答案(1)|浏览(117)

我已经创建了这个响应式布局,但我对它的实现不满意,因为它使用了JavaScript。出于各种原因,我想要一个纯CSS解决方案,主要的一个是我想动画他们。
下面是我正在寻找的响应行为的JSX和屏幕截图。基本上我想知道哪个CSS应用于SplitContentSplitContentLeftSplitContentRight来实现这个效果。

<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>
  );
};
ncecgwcz

ncecgwcz1#

使用CSS Grid:

#container {
  display: grid;
  /* Two columns by default */
  grid-template-columns: 1fr 1fr;
  /* Rows have the same width */
  grid-auto-rows: 1fr;
  /* Make blocks as dense as possible */
  grid-auto-flow: dense;
}

/* Mobile */
@media screen and (max-width: 768px) {
  #container div {
    /* Make them occupy both columns */
    grid-column: 1 / -1;
  }
}

/* Desktop */
@media screen and (min-width: 769px) {
  #container div {
    /* Span over two rows */
    grid-row-end: span 2;
  }
  .right {
    grid-column-start: 2;
  }
  #first-of-right {
    /* Right column starts at row 2 */
    grid-row-start: 2;
  }
}

试试看:

#container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 1fr;
  grid-auto-flow: dense;
}

@media screen and (max-width: 768px) {
  #container div {
    grid-column: 1 / -1;
  }
}

@media screen and (min-width: 769px) {
  #container div {
    grid-row-end: span 2;
  }
  .right {
    grid-column-start: 2;
  }
  /* :nth-child(1 of .right) */
  #first-of-right {
    grid-row-start: 2;
  }
}

/* Demo only */

* {
  box-sizing: border-box;
}

body {
  background: #eff0ff;
  font-family: system-ui;
}

#container {
  padding: 1em;
  gap: 1em;
}

#container div {
  border: 1px solid #cecfe1;
  border-radius: 0.5em;
  padding: 1.5em 2em;
}
<div id="container">
  <div>First</div>
  <div class="right" id="first-of-right">Second</div>
  <div class="right">Third</div>
  <div>Fourth</div>
  <div>Fifth</div>
</div>

将其转换为JSX应该很简单。

相关问题