首页
/ Ant Design Layout 上中下布局详解:构建经典 Header-Content-Footer 页面骨架

Ant Design Layout 上中下布局详解:构建经典 Header-Content-Footer 页面骨架

2026-09-07 15:11:12作者:董宙帆

本篇基于 Ant Design 官方示例「上中下布局」(components/layout/demo/top.md)展开,系统讲解这一最经典的「Header - Content - Footer」页面骨架的设计动机、可运行的完整实现代码,并结合 Layout 源码样式实现剖析其 flex 布局机制与 Design Token 默认值,帮助读者快速搭建结构稳定的企业级页面布局,并理解何时该选上中下布局、何时应切换到侧边布局。

什么是「上中下」布局

根据官方示例说明(top.md),这是最基本的『上-中-下』布局:

  • 主导航位于页面顶端:从左到右依次为 logo、一级导航项、辅助菜单(用户、设置、通知等)。
  • 内容区使用固定尺寸约束:通常将内容放在固定宽度(例如 1200px)内,使整个页面排版稳定,不受用户终端显示器尺寸影响。
  • 符合浏览习惯:上下级的结构符合用户自上而下浏览的习惯,是较为经典的网站导航模式。
  • 效率与代价的权衡:页面上下切分的方式提高了主工作区域的信息展示效率,但在纵向空间上会有一些牺牲。
  • 适用边界:由于导航栏水平空间的限制,这种模式不适合一级导航项很多的信息结构——导航项过多时水平空间无法容纳,此时应考虑侧边布局或顶部-侧边组合布局。

英文版文档(同一文件中 en-US 部分)的表述为:The most basic "header-content-footer" layout. Top-bottom structure is conformed with the top-bottom viewing habit, it's a classical navigation pattern of websites. This pattern demonstrates efficiency in the main workarea, while using some vertical space.

完整可运行的上中下布局示例

Ant Design 仓库中的完整示例位于 top.tsx,可直接复制到项目中使用:

import React from 'react';
import { Breadcrumb, Layout, Menu, theme } from 'antd';

const { Header, Content, Footer } = Layout;

const items = Array.from({ length: 15 }).map((_, index) => ({
  key: index + 1,
  label: `nav ${index + 1}`,
}));

const App: React.FC = () => {
  const {
    token: { colorBgContainer, borderRadiusLG },
  } = theme.useToken();

  const currentYear = new Date().getFullYear();

  return (
    <Layout>
      <Header style={{ display: 'flex', alignItems: 'center' }}>
        <div className="demo-logo" />
        <Menu
          theme="dark"
          mode="horizontal"
          defaultSelectedKeys={['2']}
          items={items}
          style={{ flex: 1, minWidth: 0 }}
        />
      </Header>
      <Content style={{ padding: '0 48px' }}>
        <Breadcrumb
          style={{ margin: '16px 0' }}
          items={[{ title: 'Home' }, { title: 'List' }, { title: 'App' }]}
        />
        <div
          style={{
            background: colorBgContainer,
            minHeight: 280,
            padding: 24,
            borderRadius: borderRadiusLG,
          }}
        >
          Content
        </div>
      </Content>
      <Footer style={{ textAlign: 'center' }}>
        Ant Design ©{currentYear} Created by Ant UED
      </Footer>
    </Layout>
  );
};

export default App;

示例中的关键技术点

  1. 三段式结构:最外层 Layout 内依次放置 HeaderContentFooter 三个子组件,正好对应『上-中-下』三个区域。官方 Layout 组件文档给出的标准嵌套形态为:

    <Layout>
      <Header>header</Header>
      <Layout>
        <Sider>left sidebar</Sider>
        <Content>main content</Content>
        <Sider>right sidebar</Sider>
      </Layout>
      <Footer>footer</Footer>
    </Layout>
    
  2. Header 内部的 flex 排布Header 上直接设置 display: 'flex', alignItems: 'center',logo 占位元素固定,Menu 通过 flex: 1, minWidth: 0 吃掉剩余空间——minWidth: 0 是 flex 子项的经典防溢出写法,避免 15 个导航项撑破水平导航栏。

  3. 深色水平菜单Menu 使用 theme="dark" + mode="horizontal",与 Header 的深色默认背景(token headerBg 默认 #001529)搭配。源码中 Header 样式特意让内嵌的 .ant-menu 继承 lineHeight(见 style/index.tslineHeight: unit(headerHeight)),使菜单项与 Header 等高对齐,这是「菜单融入顶栏」的官方集成细节。

  4. 内容卡片使用全局 Token:通过 theme.useToken() 取出 colorBgContainerborderRadiusLG,使内容区的背景色、圆角随主题自动切换(亮/暗模式),而不是写死颜色值。

  5. 面包屑 + 内容卡片Content 内以 Breadcrumb 提供路径导航,再放置一块 minHeight: 280 的内容容器,模拟真实业务页面的主工作区。

源码剖析:Header / Content / Footer 是如何生成的

阅读 layout.tsx 可以看到,四个区域组件均由同一个 generator 工厂函数从 BasicLayout 派生:

const Layout = generator({
  tagName: 'div',
  displayName: 'Layout',
})(BasicLayout);

const Header = generator({
  suffixCls: 'header',
  tagName: 'header',
  displayName: 'Header',
})(Basic);

const Footer = generator({
  suffixCls: 'footer',
  tagName: 'footer',
  displayName: 'Footer',
})(Basic);

const Content = generator({
  suffixCls: 'content',
  tagName: 'main',
  displayName: 'Content',
})(Basic);

由此得到两点值得注意的实现事实:

  • 语义化 HTMLLayout 渲染为 div,而 HeaderFooterContent 分别渲染为 <header><footer><main> 语义标签,天然对 SEO 和无障碍(screen reader 的 landmark 识别)友好。
  • 类名规则:每个组件在 Basic 中通过 getPrefixCls('layout') 得到前缀,再拼接 suffixCls,最终类名为 ant-layoutant-layout-headerant-layout-footerant-layout-contentBasic 组件还负责挂接 hashIdcssVarCls,即 CSS-in-JS 样式与 CSS 变量模式的接入点。

hasSider:为什么上中下布局是纵向 flex

BasicLayout 的核心职责之一是通过 useHasSider 判断子元素中是否存在 Sider

// components/layout/hooks/useHasSider.ts
export default function useHasSider(
  siders: string[],
  children?: React.ReactNode,
  hasSider?: boolean,
) {
  if (typeof hasSider === 'boolean') {
    return hasSider;
  }

  if (siders.length) {
    return true;
  }

  const childNodes = toArray(children);

  return childNodes.some((node) => node.type === Sider);
}

判断结果决定 ant-layout-has-sider 类名是否生效。对应到 样式层

[componentCls]: {
  display: 'flex',
  flex: 'auto',
  flexDirection: 'column',   // 默认:纵向排列,即上中下
  minHeight: 0,
  background: bodyBg,
  '&, *': { boxSizing: 'border-box' },

  [`&${componentCls}-has-sider`]: {
    flexDirection: 'row',    // 含 Sider 时:横向排列
    [`> ${componentCls}, > ${componentCls}-content`]: { width: 0 },
  },

  [`${componentCls}-header, &${componentCls}-footer`]: {
    flex: '0 0 auto',        // 头、脚固定高度,不伸缩
  },
}

对「上中下布局」而言,因为子元素中没有 Sider,Layout 保持 flex-direction: column:Header 与 Footer 都是 flex: 0 0 auto(占位固定),Content 则是 flex: auto + minHeight: 0(见 style/index.ts)——这就是中间内容区自动填满 Header 与 Footer 之间剩余空间、且可被压缩到小于内容高度的原理。minHeight: 0 上的注释表明这是修复 Firefox 中 flex 项无法收缩至内容高度以下的兼容性问题。

从源码结构看,BasicLayout 还通过 LayoutContext 向上层暴露 addSider / removeSider 钩子,供嵌套的 Sider 动态注册自己——这也是「动态增删侧边栏时 has-sider 类名能实时更新」的机制来源。hasSider 属性则如 Layout 文档 的 API 表所述,「表示子元素里有 Sider,一般不用指定。可用于服务端渲染时避免样式闪动」:SSR 首帧无法感知运行时 children 时,手动传入可避免布局方向闪动。

上中下布局相关的 Design Token

prepareComponentToken 定义了 Layout 的组件级 Token 及其默认值,直接决定示例的视觉观感:

Token 说明 默认值
headerHeight 顶部高度 controlHeight * 2(默认 64px)
headerBg 顶部背景色 #001529
headerPadding 顶部内边距 0 ${controlHeightLG * 1.25}px(默认 0 50px
headerColor 顶部文字颜色 colorText
footerBg 页脚背景色 colorBgLayout
footerPadding 页脚内边距 ${controlHeightSM}px ${controlHeightLG * 1.25}px
bodyBg 主体部分背景色 colorBgLayout

可以看到 Header 的默认高度 64px 与官方设计规范完全一致。同时源码中声明了废弃 Token 映射(DEPRECATED_TOKENS):colorBgHeader → headerBgcolorBgBody → bodyBgcolorBgTrigger → triggerBg,即旧版 colorBgHeader 等命名已废弃,新代码应直接使用上表中的 Token 名。

设计规范:高度与宽度的取值公式

Layout 文档 的「设计规则」章节给出了页面级尺寸的量化标准,可作为搭建上中下布局时的取值依据:

  • 顶部导航(大部分系统):一级导航高度 64px,二级导航 48px
  • 顶部导航(展示类页面):一级导航高度 80px,二级导航 56px
  • 顶部导航高度的范围计算公式48 + 8n
  • 侧边导航宽度的范围计算公式200 + 8n

例如默认的 headerHeight: 64px 恰好是 48 + 8×2。若需要在项目层面统一调整,可以在 ConfigProvidertheme.components.Layout 中覆盖 headerHeightheaderBg 等 Token;而一次性调整(比如让 Header 与水平菜单等高)也可以直接在 Header 上通过 style 覆盖,如示例中 display: 'flex', alignItems: 'center' 的做法。

与相邻布局模式的选型对照

官方在同一 demo 目录 下提供了完整布局族谱,上中下布局只是其中一种:

示例 说明
basic.tsx 基本结构(Layout 嵌套 Sider + Content)
top.tsx 上中下布局(本篇主题)
top-side.tsx 顶部-侧边布局
top-side-2.tsx 顶部-侧边布局-通栏
side.tsx 侧边布局
responsive.tsx 响应式布局(Sider breakpoint + collapsedWidth
fixed.tsx 固定头部
fixed-sider.tsx 固定侧边栏
component-token.tsx 组件 Token 覆盖

结合原文档的结论,选型原则可以归纳为:

  • 一级导航项少(如 5 个以内):首选上中下布局,Header 内放水平 Menu
  • 一级导航项多、需要分组或层级:改为 top-side.tsxside.tsx,把导航移到 Sider 中纵向展开——此时 Layout 自动切换为 flex-direction: row
  • 需要小屏折叠侧栏:在 responsive.tsx 基础上使用 Siderbreakpoint / collapsedWidth / onBreakpoint 属性。

小结

上中下布局是 Ant Design Layout 组件族中最简单的形态:Header<header>)与 Footer<footer>)以 flex: 0 0 auto 固定上下,Content<main>)以 flex: auto 撑满中部,整棵子树统一 box-sizing: border-box 并默认纵向 flex 排列。示例 top.tsx 展示了「深色水平菜单 + 面包屑 + Token 驱动的内容卡片」这一完整套路,而高度取值(48 + 8n)、背景色与内边距均由 style/index.ts 中的 Layout Token 统一管控,可通过 ConfigProvider 在应用级覆盖。理解 useHasSider 驱动的 ant-layout-has-sider 切换机制后,就能在同一套 Layout API 上平滑扩展出顶部-侧边、响应式等更复杂的页面骨架。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388