Layout
Handling the overall layout of a page.
Specification#
Size#
The first level navigation is inclined left near a logo, and the secondary menu is inclined right.
Top Navigation (almost systems): the height of the first level navigation
64px
, the second level navigation48px
.Top Navigation(contents page): 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 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 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 best.
Visualization rules#
Style of a navigation should conform to the its level.
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 using 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
、14px
is a standard font size of navigations,14px
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 whichHeader
Sider
Content
Footer
orLayout
itself 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
.
Based 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%', borderRight: 0 }}
>
<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,
};
onCollapse = (collapsed) => {
console.log(collapsed);
this.setState({ collapsed });
}
render() {
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider
collapsible
collapsed={this.state.collapsed}
onCollapse={this.onCollapse}
>
<div className="logo" />
<Menu theme="dark" defaultSelectedKeys={['1']} mode="inline">
<Menu.Item key="1">
<Icon type="pie-chart" />
<span>Option 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="desktop" />
<span>Option 2</span>
</Menu.Item>
<SubMenu
key="sub1"
title={<span><Icon type="user" /><span>User</span></span>}
>
<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"
title={<span><Icon type="team" /><span>Team</span></span>}
>
<Menu.Item key="6">Team 1</Menu.Item>
<Menu.Item key="8">Team 2</Menu.Item>
</SubMenu>
<Menu.Item key="9">
<Icon type="file" />
<span>File</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;
}
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>nav 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="video-camera" />
<span>nav 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="upload" />
<span>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;
}
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>
<Sider style={{ overflow: 'auto', height: '100vh', position: 'fixed', left: 0 }}>
<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 style={{ marginLeft: 200 }}>
<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 customize the styles | object | - |
className | container className | string | - |
APIs of
Layout.Header
Layout.Footer
Layout.Content
are the same as that ofLayout
.
Layout.Sider#
The sidebar.
Property | Description | Type | Default |
---|---|---|---|
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 |
collapsed | to set the current status | boolean | - |
onCollapse | the callback function, 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 customize the styles | object | - |
className | container className | string | - |
breakpoint width#
{
xs: '480px',
sm: '768px',
md: '992px',
lg: '1200px',
xl: '1600px',
}
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>