Layout
Handling the overall layout of a page.
Specification#
Size#
The first level of the navigation is placed near by a logo inclined left, and the secondary menu is placed inclined right.
Top Navigation (almost systems): the height of the first level navigation
64px, the second level of navigation48px。Top Navigation(contents page): the height of the first level navigation
80px, the second level of navigation56px。Calculation formula of a top navigation:
48+8n.Calculation formula a aside navigation:
200+8n.
Interaction rules#
The first level navigation and the last level navigation should be distincted by visualization;
The current item should have the highest priority of visualization;
When the current navigation item is collapsed, the stlye of the current navigation item will be applied to the parent level of it;
The left side navigation bar support for both the according and the expanding style, you can choose the one of it case by case.
Visualization rules#
Style of a navigation should conform to the level of it.
Emphasis by colorblock
When background color is a deep color, you can use this pattern for the parent level navigation item of 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 recommed to use it for the last item of the navigation path.
Hightlighted font
From the visualization aspect, hightlighted 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、14pxis a standard font size of navigations,14 is used for the first and the second level of the navigation. You can choose a approprigate font size in terms of the level of your navigation.
Component Overview#
Layout: The layout wrapper, in whichHeaderSiderContentFooterorLayoutitself can be nested, and can be placed in any parent container.Header: The top layout with 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 default style, in which any element can be nested, and must be placed inLayout.Footer: The bottom layout with default style, in which any element can be nested, and must be placed inLayout.
Base on
flex layout, please pay attention to the compatibility.
Examples
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
ReactDOM.render(
<div>
<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>
</div>
, 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']}
style={{ lineHeight: '64px' }}
>
<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: '12px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<div style={{ background: '#fff', padding: 24, minHeight: 280 }}>Content</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
Ant Design ©2016 Created by Ant UED
</Footer>
</Layout>
, mountNode);#components-layout-demo-top .logo {
width: 120px;
height: 31px;
background: #333;
border-radius: 6px;
margin: 16px 24px 16px 0;
float: left;
}import { Layout, Menu, Breadcrumb, Icon } from 'antd';
const { SubMenu } = Menu;
const { Header, Content, Sider } = Layout;
ReactDOM.render(
<Layout>
<Header className="header">
<div className="logo" />
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys={['2']}
style={{ lineHeight: '64px' }}
>
<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} style={{ background: '#fff' }}>
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%' }}
>
<SubMenu key="sub1" title={<span><Icon type="user" />subnav 1</span>}>
<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" title={<span><Icon type="laptop" />subnav 2</span>}>
<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" title={<span><Icon type="notification" />subnav 3</span>}>
<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: '12px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<Content style={{ background: '#fff', padding: 24, margin: 0, minHeight: 280 }}>
Content
</Content>
</Layout>
</Layout>
</Layout>
, mountNode);#components-layout-demo-top-side-2 .logo {
width: 120px;
height: 31px;
background: #333;
border-radius: 6px;
margin: 16px 28px 16px 0;
float: left;
}import { Layout, Menu, Breadcrumb, Icon } from 'antd';
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']}
style={{ lineHeight: '64px' }}
>
<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: '12px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<Layout style={{ padding: '24px 0', background: '#fff' }}>
<Sider width={200} style={{ background: '#fff' }}>
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%' }}
>
<SubMenu key="sub1" title={<span><Icon type="user" />subnav 1</span>}>
<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" title={<span><Icon type="laptop" />subnav 2</span>}>
<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" title={<span><Icon type="notification" />subnav 3</span>}>
<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 ©2016 Created by Ant UED
</Footer>
</Layout>
, mountNode);#components-layout-demo-top-side .logo {
width: 120px;
height: 31px;
background: #333;
border-radius: 6px;
margin: 16px 28px 16px 0;
float: left;
}import { Layout, Menu, Breadcrumb, Icon } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
const SubMenu = Menu.SubMenu;
class SiderDemo extends React.Component {
state = {
collapsed: false,
mode: 'inline',
};
onCollapse = (collapsed) => {
console.log(collapsed);
this.setState({
collapsed,
mode: collapsed ? 'vertical' : 'inline',
});
}
render() {
return (
<Layout>
<Sider
collapsible
collapsed={this.state.collapsed}
onCollapse={this.onCollapse}
>
<div className="logo" />
<Menu theme="dark" mode={this.state.mode} defaultSelectedKeys={['6']}>
<SubMenu
key="sub1"
title={<span><Icon type="user" /><span className="nav-text">User</span></span>}
>
<Menu.Item key="1">Tom</Menu.Item>
<Menu.Item key="2">Bill</Menu.Item>
<Menu.Item key="3">Alex</Menu.Item>
</SubMenu>
<SubMenu
key="sub2"
title={<span><Icon type="team" /><span className="nav-text">Team</span></span>}
>
<Menu.Item key="4">Team 1</Menu.Item>
<Menu.Item key="5">Team 2</Menu.Item>
</SubMenu>
<Menu.Item key="6">
<span>
<Icon type="file" />
<span className="nav-text">File</span>
</span>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }} />
<Content style={{ margin: '0 16px' }}>
<Breadcrumb style={{ margin: '12px 0' }}>
<Breadcrumb.Item>User</Breadcrumb.Item>
<Breadcrumb.Item>Bill</Breadcrumb.Item>
</Breadcrumb>
<div style={{ padding: 24, background: '#fff', minHeight: 360 }}>
Bill is a cat.
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
Ant Design ©2016 Created by Ant UED
</Footer>
</Layout>
</Layout>
);
}
}
ReactDOM.render(<SiderDemo />, mountNode);#components-layout-demo-side .logo {
height: 32px;
background: #333;
border-radius: 6px;
margin: 16px;
}
#components-layout-demo-side .ant-layout-sider-collapsed .anticon {
font-size: 16px;
margin-left: 8px;
}
#components-layout-demo-side .ant-layout-sider-collapsed .nav-text {
display: none;
}
#components-layout-demo-side .ant-layout-sider-collapsed .ant-menu-submenu-vertical > .ant-menu-submenu-title:after {
display: none;
}import { Layout, Menu, Icon } from 'antd';
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 type="user" />
<span className="nav-text">nav 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="video-camera" />
<span className="nav-text">nav 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="upload" />
<span className="nav-text">nav 3</span>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }}>
<Icon
className="trigger"
type={this.state.collapsed ? 'menu-unfold' : 'menu-fold'}
onClick={this.toggle}
/>
</Header>
<Content style={{ margin: '24px 16px', padding: 24, background: '#fff', minHeight: 280 }}>
Content
</Content>
</Layout>
</Layout>
);
}
}
ReactDOM.render(<SiderDemo />, mountNode);#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 16px;
cursor: pointer;
transition: color .3s;
}
#components-layout-demo-custom-trigger .trigger:hover {
color: #108ee9;
}
#components-layout-demo-custom-trigger .logo {
height: 32px;
background: #333;
border-radius: 6px;
margin: 16px;
}
#components-layout-demo-custom-trigger .ant-layout-sider-collapsed .anticon {
font-size: 16px;
}
#components-layout-demo-custom-trigger .ant-layout-sider-collapsed .nav-text {
display: none;
}import { Layout, Menu, Icon } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
ReactDOM.render(<Layout>
<Sider
breakpoint="lg"
collapsedWidth="0"
onCollapse={(collapsed, type) => { console.log(collapsed, type); }}
>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['4']}>
<Menu.Item key="1">
<Icon type="user" />
<span className="nav-text">nav 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="video-camera" />
<span className="nav-text">nav 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="upload" />
<span className="nav-text">nav 3</span>
</Menu.Item>
<Menu.Item key="4">
<Icon type="user" />
<span className="nav-text">nav 4</span>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }} />
<Content style={{ margin: '24px 16px 0' }}>
<div style={{ padding: 24, background: '#fff', minHeight: 360 }}>
content
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
Ant Design ©2016 Created by Ant UED
</Footer>
</Layout>
</Layout>, mountNode);#components-layout-demo-responsive .logo {
height: 32px;
background: #333;
border-radius: 6px;
margin: 16px;
}import { Layout, Menu, Breadcrumb } from 'antd';
const { Header, Content, Footer } = Layout;
ReactDOM.render(
<Layout>
<Header style={{ position: 'fixed', width: '100%' }}>
<div className="logo" />
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys={['2']}
style={{ lineHeight: '64px' }}
>
<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', marginTop: 64 }}>
<Breadcrumb style={{ margin: '12px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<div style={{ background: '#fff', padding: 24, minHeight: 380 }}>Content</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
Ant Design ©2016 Created by Ant UED
</Footer>
</Layout>
, mountNode);#components-layout-demo-fixed .logo {
width: 120px;
height: 31px;
background: #333;
border-radius: 6px;
margin: 16px 24px 16px 0;
float: left;
}import { Layout, Menu, Icon } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
ReactDOM.render(<Layout style={{ height: '100vh' }}>
<Sider style={{ overflow: 'auto' }}>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['4']}>
<Menu.Item key="1">
<Icon type="user" />
<span className="nav-text">nav 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="video-camera" />
<span className="nav-text">nav 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="upload" />
<span className="nav-text">nav 3</span>
</Menu.Item>
<Menu.Item key="4">
<Icon type="bar-chart" />
<span className="nav-text">nav 4</span>
</Menu.Item>
<Menu.Item key="5">
<Icon type="cloud-o" />
<span className="nav-text">nav 5</span>
</Menu.Item>
<Menu.Item key="6">
<Icon type="appstore-o" />
<span className="nav-text">nav 6</span>
</Menu.Item>
<Menu.Item key="7">
<Icon type="team" />
<span className="nav-text">nav 7</span>
</Menu.Item>
<Menu.Item key="8">
<Icon type="shop" />
<span className="nav-text">nav 8</span>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }} />
<Content style={{ margin: '24px 16px 0', overflow: 'initial' }}>
<div style={{ padding: 24, background: '#fff', 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 ©2016 Created by Ant UED
</Footer>
</Layout>
</Layout>, mountNode);#components-layout-demo-fixed-sider .logo {
height: 32px;
background: #333;
border-radius: 6px;
margin: 16px;
}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 |
|---|---|---|---|
| style | to custom the styles | object | - |
| className | container className | string | - |
API of
Layout.HeaderLayout.FooterLayout.Contentis the same withLayout.
Layout.Sider#
The sidebar.
| Property | Description | Type | Default |
|---|---|---|---|
| collapsible | whether can be collapsed | boolean | false |
| defaultCollapsed | to set the initial status | boolean | false |
| collapsed | to set the current status | boolean | - |
| onCollapse | the callback function, can be executed by clicking the trigger or activating the responsive layout | (collapsed, type) => {} | - |
| trigger | specify the customized trigger, set to null to hide the trigger | string|ReactNode | - |
| width | width of the sidebar | number|string | 200 |
| collapsedWidth | width of the collapsed sidebar, by setting to 0 a special trigger will appear | number | 64 |
| breakpoint | breakpoint of the responsive layout | Enum { 'xs', 'sm', 'md', 'lg', 'xl' } | - |
| style | to custom the styles | object | - |
| className | container className | string | - |
Note: If you want to wrap the
Sider, do not forget to add this setting to the customized component:__ANT_LAYOUT_SIDER = true. e.g.
const CustomizedSider = (props) => <Sider {...props} />
CustomizedSider.__ANT_LAYOUT_SIDER = true;
...
<CustomizedSider>Sider Content</CustomizedSider>