Layout
Handling the overall layout of a page.
Specification#
Size#
The first level navigation is left aligned near a logo, and the secondary menu is right aligned.
Top Navigation: the height of the first level navigation
64px
, the second level navigation48px
.Top Navigation (for landing pages): the height of the first level navigation
80px
, the second level navigation56px
.Calculation formula of a top navigation:
48+8n
.Calculation formula of an aside navigation:
200+8n
.
Interaction rules#
The first level navigation and the last level navigation should be distinguishable by visualization;
The current item should have the highest priority of visualization;
When the current navigation item is collapsed, the style of the current navigation item is applied to its parent level;
The left side navigation bar has support for both the accordion and expanding styles; you can choose the one that fits your case the best.
Visualization rules#
Style of a navigation should conform to its level.
Emphasis by colorblock
When background color is a deep color, you can use this pattern for the parent level navigation item of the current page.
The highlight match stick
When background color is a light color, you can use this pattern for the current page navigation item; we recommend using it for the last item of the navigation path.
Highlighted font
From the visualization aspect, a highlighted font is stronger than colorblock; this pattern is often used for the parent level of the current item.
Enlarge the size of the font
12px
,14px
is a standard font size of navigations,14px
is used for the first and the second level of the navigation. You can choose an appropriate font size regarding the level of your navigation.
Component Overview#
Layout
: The layout wrapper, in whichHeader
Sider
Content
Footer
orLayout
itself can be nested, and can be placed in any parent container.Header
: The top layout with the default style, in which any element can be nested, and must be placed inLayout
.Sider
: The sidebar with default style and basic functions, in which any element can be nested, and must be placed inLayout
.Content
: The content layout with the default style, in which any element can be nested, and must be placed inLayout
.Footer
: The bottom layout with the default style, in which any element can be nested, and must be placed inLayout
.
Based on
flex layout
, please pay attention to the compatibility.
Examples
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
ReactDOM.render(
<>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<Layout>
<Sider>Sider</Sider>
<Content>Content</Content>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<Layout>
<Content>Content</Content>
<Sider>Sider</Sider>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Sider>Sider</Sider>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
</Layout>
</>,
mountNode,
);
import { Layout, Menu, Breadcrumb } from 'antd';
const { Header, Content, Footer } = Layout;
ReactDOM.render(
<Layout className="layout">
<Header>
<div className="logo" />
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']}>
{new Array(15).fill(null).map((_, index) => {
const key = index + 1;
return <Menu.Item key={key}>{`nav ${key}`}</Menu.Item>;
})}
</Menu>
</Header>
<Content style={{ padding: '0 50px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<div className="site-layout-content">Content</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>,
mountNode,
);
.site-layout-content {
min-height: 280px;
padding: 24px;
background: #fff;
}
#components-layout-demo-top .logo {
float: left;
width: 120px;
height: 31px;
margin: 16px 24px 16px 0;
background: rgba(255, 255, 255, 0.3);
}
.ant-row-rtl #components-layout-demo-top .logo {
float: right;
margin: 16px 0 16px 24px;
}
import { Layout, Menu, Breadcrumb } from 'antd';
import { UserOutlined, LaptopOutlined, NotificationOutlined } from '@ant-design/icons';
const { SubMenu } = Menu;
const { Header, Content, Sider } = Layout;
ReactDOM.render(
<Layout>
<Header className="header">
<div className="logo" />
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']}>
<Menu.Item key="1">nav 1</Menu.Item>
<Menu.Item key="2">nav 2</Menu.Item>
<Menu.Item key="3">nav 3</Menu.Item>
</Menu>
</Header>
<Layout>
<Sider width={200} className="site-layout-background">
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%', borderRight: 0 }}
>
<SubMenu key="sub1" icon={<UserOutlined />} title="subnav 1">
<Menu.Item key="1">option1</Menu.Item>
<Menu.Item key="2">option2</Menu.Item>
<Menu.Item key="3">option3</Menu.Item>
<Menu.Item key="4">option4</Menu.Item>
</SubMenu>
<SubMenu key="sub2" icon={<LaptopOutlined />} title="subnav 2">
<Menu.Item key="5">option5</Menu.Item>
<Menu.Item key="6">option6</Menu.Item>
<Menu.Item key="7">option7</Menu.Item>
<Menu.Item key="8">option8</Menu.Item>
</SubMenu>
<SubMenu key="sub3" icon={<NotificationOutlined />} title="subnav 3">
<Menu.Item key="9">option9</Menu.Item>
<Menu.Item key="10">option10</Menu.Item>
<Menu.Item key="11">option11</Menu.Item>
<Menu.Item key="12">option12</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Layout style={{ padding: '0 24px 24px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<Content
className="site-layout-background"
style={{
padding: 24,
margin: 0,
minHeight: 280,
}}
>
Content
</Content>
</Layout>
</Layout>
</Layout>,
mountNode,
);
#components-layout-demo-top-side-2 .logo {
float: left;
width: 120px;
height: 31px;
margin: 16px 24px 16px 0;
background: rgba(255, 255, 255, 0.3);
}
.ant-row-rtl #components-layout-demo-top-side-2 .logo {
float: right;
margin: 16px 0 16px 24px;
}
.site-layout-background {
background: #fff;
}
import { Layout, Menu, Breadcrumb } from 'antd';
import { UserOutlined, LaptopOutlined, NotificationOutlined } from '@ant-design/icons';
const { SubMenu } = Menu;
const { Header, Content, Footer, Sider } = Layout;
ReactDOM.render(
<Layout>
<Header className="header">
<div className="logo" />
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']}>
<Menu.Item key="1">nav 1</Menu.Item>
<Menu.Item key="2">nav 2</Menu.Item>
<Menu.Item key="3">nav 3</Menu.Item>
</Menu>
</Header>
<Content style={{ padding: '0 50px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<Layout className="site-layout-background" style={{ padding: '24px 0' }}>
<Sider className="site-layout-background" width={200}>
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%' }}
>
<SubMenu key="sub1" icon={<UserOutlined />} title="subnav 1">
<Menu.Item key="1">option1</Menu.Item>
<Menu.Item key="2">option2</Menu.Item>
<Menu.Item key="3">option3</Menu.Item>
<Menu.Item key="4">option4</Menu.Item>
</SubMenu>
<SubMenu key="sub2" icon={<LaptopOutlined />} title="subnav 2">
<Menu.Item key="5">option5</Menu.Item>
<Menu.Item key="6">option6</Menu.Item>
<Menu.Item key="7">option7</Menu.Item>
<Menu.Item key="8">option8</Menu.Item>
</SubMenu>
<SubMenu key="sub3" icon={<NotificationOutlined />} title="subnav 3">
<Menu.Item key="9">option9</Menu.Item>
<Menu.Item key="10">option10</Menu.Item>
<Menu.Item key="11">option11</Menu.Item>
<Menu.Item key="12">option12</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Content style={{ padding: '0 24px', minHeight: 280 }}>Content</Content>
</Layout>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>,
mountNode,
);
#components-layout-demo-top-side .logo {
float: left;
width: 120px;
height: 31px;
margin: 16px 24px 16px 0;
background: rgba(255, 255, 255, 0.3);
}
.ant-row-rtl #components-layout-demo-top-side .logo {
float: right;
margin: 16px 0 16px 24px;
}
.site-layout-background {
background: #fff;
}
import { Layout, Menu, Breadcrumb } from 'antd';
import {
DesktopOutlined,
PieChartOutlined,
FileOutlined,
TeamOutlined,
UserOutlined,
} from '@ant-design/icons';
const { Header, Content, Footer, Sider } = Layout;
const { SubMenu } = Menu;
class SiderDemo extends React.Component {
state = {
collapsed: false,
};
onCollapse = collapsed => {
console.log(collapsed);
this.setState({ collapsed });
};
render() {
const { collapsed } = this.state;
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider collapsible collapsed={collapsed} onCollapse={this.onCollapse}>
<div className="logo" />
<Menu theme="dark" defaultSelectedKeys={['1']} mode="inline">
<Menu.Item key="1" icon={<PieChartOutlined />}>
Option 1
</Menu.Item>
<Menu.Item key="2" icon={<DesktopOutlined />}>
Option 2
</Menu.Item>
<SubMenu key="sub1" icon={<UserOutlined />} title="User">
<Menu.Item key="3">Tom</Menu.Item>
<Menu.Item key="4">Bill</Menu.Item>
<Menu.Item key="5">Alex</Menu.Item>
</SubMenu>
<SubMenu key="sub2" icon={<TeamOutlined />} title="Team">
<Menu.Item key="6">Team 1</Menu.Item>
<Menu.Item key="8">Team 2</Menu.Item>
</SubMenu>
<Menu.Item key="9" icon={<FileOutlined />}>
Files
</Menu.Item>
</Menu>
</Sider>
<Layout className="site-layout">
<Header className="site-layout-background" style={{ padding: 0 }} />
<Content style={{ margin: '0 16px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>User</Breadcrumb.Item>
<Breadcrumb.Item>Bill</Breadcrumb.Item>
</Breadcrumb>
<div className="site-layout-background" style={{ padding: 24, minHeight: 360 }}>
Bill is a cat.
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>
</Layout>
);
}
}
ReactDOM.render(<SiderDemo />, mountNode);
#components-layout-demo-side .logo {
height: 32px;
margin: 16px;
background: rgba(255, 255, 255, 0.3);
}
.site-layout .site-layout-background {
background: #fff;
}
import { Layout, Menu } from 'antd';
import {
MenuUnfoldOutlined,
MenuFoldOutlined,
UserOutlined,
VideoCameraOutlined,
UploadOutlined,
} from '@ant-design/icons';
const { Header, Sider, Content } = Layout;
class SiderDemo extends React.Component {
state = {
collapsed: false,
};
toggle = () => {
this.setState({
collapsed: !this.state.collapsed,
});
};
render() {
return (
<Layout>
<Sider trigger={null} collapsible collapsed={this.state.collapsed}>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
<Menu.Item key="1" icon={<UserOutlined />}>
nav 1
</Menu.Item>
<Menu.Item key="2" icon={<VideoCameraOutlined />}>
nav 2
</Menu.Item>
<Menu.Item key="3" icon={<UploadOutlined />}>
nav 3
</Menu.Item>
</Menu>
</Sider>
<Layout className="site-layout">
<Header className="site-layout-background" style={{ padding: 0 }}>
{React.createElement(this.state.collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
className: 'trigger',
onClick: this.toggle,
})}
</Header>
<Content
className="site-layout-background"
style={{
margin: '24px 16px',
padding: 24,
minHeight: 280,
}}
>
Content
</Content>
</Layout>
</Layout>
);
}
}
ReactDOM.render(<SiderDemo />, mountNode);
#components-layout-demo-custom-trigger .trigger {
padding: 0 24px;
font-size: 18px;
line-height: 64px;
cursor: pointer;
transition: color 0.3s;
}
#components-layout-demo-custom-trigger .trigger:hover {
color: #1890ff;
}
#components-layout-demo-custom-trigger .logo {
height: 32px;
margin: 16px;
background: rgba(255, 255, 255, 0.3);
}
.site-layout .site-layout-background {
background: #fff;
}
import { Layout, Menu } from 'antd';
import { UploadOutlined, UserOutlined, VideoCameraOutlined } from '@ant-design/icons';
const { Header, Content, Footer, Sider } = Layout;
ReactDOM.render(
<Layout>
<Sider
breakpoint="lg"
collapsedWidth="0"
onBreakpoint={broken => {
console.log(broken);
}}
onCollapse={(collapsed, type) => {
console.log(collapsed, type);
}}
>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['4']}>
<Menu.Item key="1" icon={<UserOutlined />}>
nav 1
</Menu.Item>
<Menu.Item key="2" icon={<VideoCameraOutlined />}>
nav 2
</Menu.Item>
<Menu.Item key="3" icon={<UploadOutlined />}>
nav 3
</Menu.Item>
<Menu.Item key="4" icon={<UserOutlined />}>
nav 4
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header className="site-layout-sub-header-background" style={{ padding: 0 }} />
<Content style={{ margin: '24px 16px 0' }}>
<div className="site-layout-background" style={{ padding: 24, minHeight: 360 }}>
content
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>
</Layout>,
mountNode,
);
#components-layout-demo-responsive .logo {
height: 32px;
margin: 16px;
background: rgba(255, 255, 255, 0.2);
}
.site-layout-sub-header-background {
background: #fff;
}
.site-layout-background {
background: #fff;
}
import { Layout, Menu, Breadcrumb } from 'antd';
const { Header, Content, Footer } = Layout;
ReactDOM.render(
<Layout>
<Header style={{ position: 'fixed', zIndex: 1, width: '100%' }}>
<div className="logo" />
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']}>
<Menu.Item key="1">nav 1</Menu.Item>
<Menu.Item key="2">nav 2</Menu.Item>
<Menu.Item key="3">nav 3</Menu.Item>
</Menu>
</Header>
<Content className="site-layout" style={{ padding: '0 50px', marginTop: 64 }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<div className="site-layout-background" style={{ padding: 24, minHeight: 380 }}>
Content
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>,
mountNode,
);
#components-layout-demo-fixed .logo {
float: left;
width: 120px;
height: 31px;
margin: 16px 24px 16px 0;
background: rgba(255, 255, 255, 0.2);
}
.site-layout .site-layout-background {
background: #fff;
}
import { Layout, Menu } from 'antd';
import {
AppstoreOutlined,
BarChartOutlined,
CloudOutlined,
ShopOutlined,
TeamOutlined,
UserOutlined,
UploadOutlined,
VideoCameraOutlined,
} from '@ant-design/icons';
const { Header, Content, Footer, Sider } = Layout;
ReactDOM.render(
<Layout hasSider>
<Sider
style={{
overflow: 'auto',
height: '100vh',
position: 'fixed',
left: 0,
top: 0,
bottom: 0,
}}
>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['4']}>
<Menu.Item key="1" icon={<UserOutlined />}>
nav 1
</Menu.Item>
<Menu.Item key="2" icon={<VideoCameraOutlined />}>
nav 2
</Menu.Item>
<Menu.Item key="3" icon={<UploadOutlined />}>
nav 3
</Menu.Item>
<Menu.Item key="4" icon={<BarChartOutlined />}>
nav 4
</Menu.Item>
<Menu.Item key="5" icon={<CloudOutlined />}>
nav 5
</Menu.Item>
<Menu.Item key="6" icon={<AppstoreOutlined />}>
nav 6
</Menu.Item>
<Menu.Item key="7" icon={<TeamOutlined />}>
nav 7
</Menu.Item>
<Menu.Item key="8" icon={<ShopOutlined />}>
nav 8
</Menu.Item>
</Menu>
</Sider>
<Layout className="site-layout" style={{ marginLeft: 200 }}>
<Header className="site-layout-background" style={{ padding: 0 }} />
<Content style={{ margin: '24px 16px 0', overflow: 'initial' }}>
<div className="site-layout-background" style={{ padding: 24, textAlign: 'center' }}>
...
<br />
Really
<br />
...
<br />
...
<br />
...
<br />
long
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
...
<br />
content
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>
</Layout>,
mountNode,
);
#components-layout-demo-fixed-sider .logo {
height: 32px;
margin: 16px;
background: rgba(255, 255, 255, 0.2);
}
.site-layout .site-layout-background {
background: #fff;
}
API#
<Layout>
<Header>header</Header>
<Layout>
<Sider>left sidebar</Sider>
<Content>main content</Content>
<Sider>right sidebar</Sider>
</Layout>
<Footer>footer</Footer>
</Layout>
Layout#
The wrapper.
Property | Description | Type | Default |
---|---|---|---|
className | Container className | string | - |
hasSider | Whether contain Sider in children, don't have to assign it normally. Useful in ssr avoid style flickering | boolean | - |
style | To customize the styles | CSSProperties | - |
Layout.Sider#
The sidebar.
Property | Description | Type | Default |
---|---|---|---|
breakpoint | Breakpoints of the responsive layout | xs | sm | md | lg | xl | xxl | - |
className | Container className | string | - |
collapsed | To set the current status | boolean | - |
collapsedWidth | Width of the collapsed sidebar, by setting to 0 a special trigger will appear | number | 80 |
collapsible | Whether can be collapsed | boolean | false |
defaultCollapsed | To set the initial status | boolean | false |
reverseArrow | Reverse direction of arrow, for a sider that expands from the right | boolean | false |
style | To customize the styles | CSSProperties | - |
theme | Color theme of the sidebar | light | dark | dark |
trigger | Specify the customized trigger, set to null to hide the trigger | ReactNode | - |
width | Width of the sidebar | number | string | 200 |
zeroWidthTriggerStyle | To customize the styles of the special trigger that appears when collapsedWidth is 0 | object | - |
onBreakpoint | The callback function, executed when breakpoints changed | (broken) => {} | - |
onCollapse | The callback function, executed by clicking the trigger or activating the responsive layout | (collapsed, type) => {} | - |
breakpoint width#
{
xs: '480px',
sm: '576px',
md: '768px',
lg: '992px',
xl: '1200px',
xxl: '1600px',
}