CSS书籍布局(水平手风琴)

mar*_*lle 4 javascript css reactjs

我正在尝试创建一个具有书籍布局的页面,因此带有一些使用的选项卡的页面可以一次展开一个。

这是一个工作示例:https://codesandbox.io/s/book-layout-l28gh ?file=/src/App.js:0-1419

import { useState } from "react";

const dataset = [
  { name: "A section", description: "page A" },
  { name: "B section", description: "page B" },
  { name: "C section with long title", description: "page C" },
  { name: "D section", description: "page D" }
];

export default function App() {
  return <Page />;
}

function Page({}) {
  const [openSection, setOpenSection] = useState(0);

  return (
    <div
      style={{
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        height: "100vh"
      }}
    >
      {dataset.map((datum, i) => {
        const { name } = datum;
        const isOpen = i === openSection;

        return (
          <div
            key={name}
            style={{
              height: "100%",
              backgroundColor: isOpen ? "white" : "lightgray",
              border: `1px solid ${isOpen ? "white" : "black"}`,
              padding: 10,
              flex: 1,
              flexGrow: isOpen ? 1 : 0,
              transition: "all 2s ease"
            }}
          >
            <div
              style={{
                cursor: "pointer",
                writingMode: isOpen ? "horizontal-tb" : "vertical-rl",
                transition: "all 2s ease"
              }}
              onClick={() => setOpenSection(i)}
            >
              {name}
            </div>
          </div>
        );
      })}
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

如果你测试一下,你会发现一些问题:

  1. 当您展开一个部分时,标题不会平滑过渡,从垂直到水平。应该是平滑的旋转
  2. 有时,我不明白什么时候,当你点击一个标题时,所有的卡片似乎都变得更加接近。
  3. 另一个要求是让灰色区域全部可点击,但打开时很明显有问题

为什么?有什么问题?有没有更好的方法来进行这样的布局?

Muh*_*our 5

我按照你说的解决了你所有的问题。

问题#1 -> 已解决: 您应该使用white-space:nowrap. 如果您的文本很大,那么在框的末尾,它将断到下一行。white-space:nowrap别让那样。(我不建议这样做,因为这对于太长的标题文本不利。)

问题#2 -> 已解决:当您单击某个项目并在操作过程中(打开框)单击另一个项目时,会发生这种情况。这是因为display: flexflexGrow: 1

您使用了弹性盒和justifyContent: "center". 因此,当您点击另一张卡片时,您的包装纸就会变小,并且所有卡片似乎都彼此靠近。flexGrow: 1会打破他们。解决方案也是如此flexGrow: 5

问题 #3 -> 已解决:设置位置错误onClick。您应该在您的盒子上而不是在您的文本上设置onClick事件。光标的条件就是你想要的。(项目已选择,因此光标必须为default,否则必须为poiner)。

奖励:)如果你为你的包装纸设置一个小宽度,这样你的旋转框就会更漂亮。它在文本和宾果游戏开始时旋转。

import { useState } from "react";

const dataset = [
  { name: "A section" },
  { name: "B section" },
  { name: "C section with long title" },
  { name: "D section" },
  { name: "E section" },
];

function Page() {
  const [openSection, setOpenSection] = useState(1);

  return (
    <div
      style={{
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        height: "100vh",
      }}
    >
      {dataset.map((datum, i) => {
        const { name } = datum;
        const isOpen = i === openSection;
        return (
          <div
            key={name}
            onClick={() => setOpenSection(i)}
            style={{
              height: "100%",
              backgroundColor: isOpen ? "white" : "lightgray",
              border: `1px solid ${isOpen ? "white" : "black"}`,
              padding: "20px 30px",
              flex: 1,
              flexGrow: isOpen ? 5 : 0,
              transition: "all 1s linear",
              boxSizing: "border-box",
              cursor: openSection !== i ? 'pointer' : 'default',

              "&:first-child": {
                left: 0,
              },

              "&:last-child": {
                right: 0,
              },
            }}
          >
            <div
              style={{
                transform: `rotate(${isOpen ? "0" : "90"}deg)`,
                transition: "all 1s linear",
                width: 1,
                whiteSpace: "nowrap",
              }}
            >
              {name}
            </div>
          </div>
        );
      })}
    </div>
  );
}

export default Page;
Run Code Online (Sandbox Code Playgroud)