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

React项目中粘性侧边栏初始水平溢出视口,滚动后恢复的问题求助

React项目中粘性侧边栏初始水平溢出视口,滚动后恢复的问题求助

我最近在用React+Tailwind做一个博客项目,遇到个奇怪的布局问题:页面加载时侧边栏(FilterSideMenu)会水平溢出视口,但稍微滚动一下页面,它就自动回到MainLayout设定的padding范围内了,实在搞不懂为啥。

先给大家看一下我的代码结构:

首先是全局的MainLayout组件,用Tailwind的padding类给所有页面统一设置了左右内边距:

import React from "react";
import Navbar from "./Navbar";
import { Outlet } from "react-router-dom";

function MainLayout() {
  return (
    // <div className="px-4 md:px-24 lg:px-32 xl:px-42 2xl:px-60">
    <div className="px-4 md:px-8 lg:px-16 lx:px-32 2xl:px-64">
      <Navbar />
      <Outlet />
    </div>
  );
}

export default MainLayout;

然后是出现问题的PostListPage页面,里面包含了文章列表和侧边筛选菜单,还做了移动端的展开/收起按钮:

import React, { useState } from "react";
import PostList from "../components/PostList";
import FilterSideMenu from "../components/FilterSideMenu";

function PostListPage() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <div className="mb-10 mt-6">
        <h1 className="text-2xl mb-6">Example Blog</h1>

        <button
          onClick={() => setOpen((prev) => !prev)}
          className="bg-secondaryColor px-4 py-2 md:hidden mt-6 mb-6 rounded-lg dark:text-black"
        >
          {open ? "Close" : "Filter or Search"}
        </button>

        <div className="flex flex-col-reverse gap-8 md:flex-row justify-between">
          <div>
            <PostList />
          </div>
          <div className={`${open ? "block" : "hidden"} md:block`}>
            <FilterSideMenu />
          </div>
        </div>
      </div>
    </>
  );
}

export default PostListPage;

最后是侧边栏组件FilterSideMenu,用了sticky定位让它跟着滚动:

import React from "react";
import { Link } from "react-router-dom";
import Search from "./Search";

function FilterSideMenu() {
  return (
    <div className="px-6 h-max sticky top-10 dark:bg-gray-600 bg-gray-100 p-4 rounded-2xl">
      <div className="flex flex-col gap-8">
        <div>
          <span className="font-medium mb-2 block">Search</span>
          <Search />
        </div>
        <div className="flex flex-row md:gap-4 md:flex-col gap-32">
          <div>
            <span className="font-medium">Filter</span>
            <div className="flex flex-col gap-2 mt-2 text-sm">
              <label
                htmlFor="newest"
                className="flex items-center gap-2 cursor-pointer"
              >
                <input
                  type="radio"
                  id="newest"
                  name="sort"
                  value="newest"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Newest
              </label>
              <label
                htmlFor=""
                name="sort"
                value="popular"
                className="flex items-center gap-2 cursor-pointer"
              >
                <input
                  type="radio"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Most Popular
              </label>
              <label
                htmlFor=""
                name="sort"
                value="trending"
                className="flex items-center gap-2 cursor-pointer "
              >
                <input
                  type="radio"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Trending
              </label>
              <label
                htmlFor=""
                name="sort"
                value="oldest"
                className="flex items-center gap-2 cursor-pointer "
              >
                <input
                  type="radio"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Oldest
              </label>
            </div>
          </div>
          <div className="">
            <span className="font-medium">Categories</span>
            <div className="flex flex-col underline gap-2 mt-4 text-sm">
              <Link to="/posts?cat=all">All</Link>
              <Link to="/posts?cat=categ1">Categ1</Link>
              <Link to="/posts?cat=categ1">Categ2</Link>
              <Link to="/posts?cat=categ1">Categ3</Link>
              <Link to="/posts?cat=categ1">Categ4</Link>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default FilterSideMenu;

我已经排查过这些点:

  • 确认FilterSideMenu确实被包裹在MainLayout的padding容器里
  • 检查了所有CSS类,没发现冲突的margin或padding
  • 用浏览器开发者工具观察,发现滚动后页面会重新计算布局(重排/重绘),侧边栏就正常了

我的期望是:页面加载时,侧边栏就能立刻遵守MainLayout设置的padding,不需要滚动一下才正常。有没有大佬遇到过类似问题,给我指点一下?

备注:内容来源于stack exchange,提问作者Sowmith Sripadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:33:15