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

Chakra UI+Next.js侧边栏展开时文本短暂垂直问题求助

解决Chakra UI + Next.js侧边栏展开时文本短暂垂直的问题

问题根源有两个:

  • 侧边栏宽度仅在展开时应用过渡,收起时无过渡,导致宽度突变触发布局重排
  • 文本用display: none/flex切换显示,元素突然加入DOM时,侧边栏宽度还没完全展开,HStack空间不足导致文本换行垂直显示

修复步骤:

  1. 统一侧边栏宽度过渡
    把侧边栏容器的transition属性改为始终生效,避免宽度突变:
<Box
  as="nav"
  position="fixed"
  left="0"
  top="0"
  bg="black"
  h="100vh"
  w={isOpen ? "200px" : "78px"}
  transition="width 0.3s" // 移除条件判断,始终应用宽度过渡
>
  1. 优化文本显示过渡
    用opacity和width替代display切换,让文本平滑显示/隐藏,同时强制不换行:
<Text
  opacity={isOpen ? 1 : 0}
  width={isOpen ? "auto" : 0}
  whiteSpace="nowrap"
  overflow="hidden"
  color="white"
  ml={2}
  transition="opacity 0.2s, width 0.3s" // 添加透明度和宽度的过渡
>
  {label}
</Text>

修改后的完整代码:

import {
  Box,
  chakra,
  HStack,
  IconButton,
  Text,
  useColorModeValue,
  VStack
} from "@chakra-ui/react";
import * as React from "react";
import { FiFileText, FiMenu, FiSettings, FiUser } from "react-icons/fi";

interface SidebarItemProps {
  icon: JSX.Element;
  isOpen: boolean;
  label: string;
}

const SidebarItem: React.FC<SidebarItemProps> = ({ icon, isOpen, label }) => {
  const hoverColor = useColorModeValue("gray.600", "gray.300");

  return (
    <chakra.div
      role="group"
      _hover={{ bg: hoverColor }}
      transition="background-color 0.2s"
      borderRadius="md"
      w="100%"
    >
      <HStack alignItems="center" p={2} maxW="100%">
        <IconButton
          aria-label={label}
          icon={icon}
          size="sm"
          variant="ghost"
          _groupHover={{ bg: "transparent" }}
          boxSize={6}
        />
        <Text
          opacity={isOpen ? 1 : 0}
          width={isOpen ? "auto" : 0}
          whiteSpace="nowrap"
          overflow="hidden"
          color="white"
          ml={2}
          transition="opacity 0.2s, width 0.3s"
        >
          {label}
        </Text>
      </HStack>
    </chakra.div>
  );
};

export const Sidebar: React.FC = () => {
  const [isOpen, setIsOpen] = React.useState(false);

  const handleToggle = () => {
    setIsOpen(!isOpen);
  };

  return (
    <Box
      as="nav"
      position="fixed"
      left="0"
      top="0"
      bg="black"
      h="100vh"
      w={isOpen ? "200px" : "78px"}
      transition="width 0.3s"
    >
      <VStack align="start" p={4}>
        <IconButton
          aria-label="Toggle Menu"
          icon={<FiMenu />}
          onClick={handleToggle}
          mb={6}
          w="12"
        />

        <VStack w="100%" align="start" spacing={6}>
          <SidebarItem icon={<FiUser />} isOpen={isOpen} label="ユーザー" />
          <SidebarItem icon={<FiFileText />} isOpen={isOpen} label="投稿" />
          <SidebarItem icon={<FiSettings />} isOpen={isOpen} label="管理" />
        </VStack>
      </VStack>
    </Box>
  );
};

这样修改后,侧边栏宽度变化平滑,文本会随着宽度展开逐渐显示,不会出现短暂垂直的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:32:09