Layout

Layout and Navigation is the backbone of productions, it is one of the most important design pattern of a page, and it is also a base when you create a page, it will establish a interactive and visual style for a production.

The Layout and Navigation design specification for Ant Design are as follows:

The specification of 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 navigation 48px

  • Top Navigation(contents page): the height of the first level navigation 80px,the second level of navigation 56px

  • Calculation formula of a top navigation:48+8n.

  • Calculation formula a aside navigation:200+8n.

The principle of interaction#

  • 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.

The principle of visualization#

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

    12px14px is 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.

In almost middle-back systems, Ant Design uses two general layouts of top navigation and aside navition, we collect some basic layouts of middle-back systems are designed by Ant Design as follows. The demo code below is used of sample, you should Layout component in real project.

Examples

Home/App list/Any app/

The first and second level nav are both on the top.

A top-bottom structure of page layouts is used for top navigation. Generally, the mainnav is placed at the top of the page, and includes the logo, the first level navigation, and the secondary menu (users, settings, notifications) from left to right in it. We always put contents in a fixed size navigation (eg: 1200px), the layout of the whole page is stable, it's not affected by viewing area.

Top-bottom structure is conform 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. And because the horizontal space of the navigation is limited, this pattern is not suitable for cases when the first level navigation contains many elements or links.

<BrowserDemo /> This is for demo, don't need to copy.

import { Menu, Breadcrumb } from 'antd';
import BrowserDemo from 'site/theme/template/BrowserDemo';

ReactDOM.render(
  <BrowserDemo>
    <div className="layout-top">
      <div className="layout-header">
        <div className="layout-wrapper">
          <div className="layout-logo"></div>
          <Menu theme="dark" mode="horizontal"
            defaultSelectedKeys={['2']} style={{lineHeight: '64px'}}>
            <Menu.Item key="1">Navigation 1</Menu.Item>
            <Menu.Item key="2">Navigation 2</Menu.Item>
            <Menu.Item key="3">Navigation 3</Menu.Item>
          </Menu>
        </div>
      </div>
      <div className="layout-subheader">
        <div className="layout-wrapper">
          <Menu mode="horizontal"
            defaultSelectedKeys={['1']} style={{marginLeft: 124}}>
            <Menu.Item key="1">Second nav</Menu.Item>
            <Menu.Item key="2">Second nav</Menu.Item>
            <Menu.Item key="3">Second nav</Menu.Item>
          </Menu>
        </div>
      </div>
      <div className="layout-wrapper">
        <Breadcrumb>
          <Breadcrumb.Item>Home</Breadcrumb.Item>
          <Breadcrumb.Item>App list</Breadcrumb.Item>
          <Breadcrumb.Item>Any app</Breadcrumb.Item>
        </Breadcrumb>
        <div className="layout-container">
          <div style={{ height: 210 }}></div>
        </div>
      </div>
      <div className="layout-footer">
        Ant Design all rights reserved © 2015 Created by Ant UED
      </div>
    </div>
  </BrowserDemo>
, mountNode);
.layout-top {
  height: 100%;
}

.layout-top .layout-wrapper {
  padding: 0 50px;
}

.layout-top .layout-header {
  background: #404040;
  height: 64px;
}

.layout-top .layout-logo {
  width: 120px;
  height: 32px;
  background: #333;
  border-radius: 4px;
  margin: 16px 24px 16px 0;
  float: left;
}

.layout-top .layout-subheader {
  height: 48px;
  border-bottom: 1px solid #e9e9e9;
  background: #fff;
  margin-bottom: 12px;
}

.layout-top .layout-container {
  background: #fff;
  margin: 12px 0 0;
  position: relative;
  padding-top: 24px;
  overflow: hidden;
  border-radius: 4px;
}

.layout-top .layout-footer {
  height: 64px;
  line-height: 64px;
  text-align: center;
  font-size: 12px;
  color: #999;
}
Home/App list/Any app/
Contents

The top navigation is placed on the top, and the secondary navigation is placed on the aside.

import { Menu, Breadcrumb, Icon } from 'antd';
import BrowserDemo from 'site/theme/template/BrowserDemo';
const SubMenu = Menu.SubMenu;

ReactDOM.render(
  <BrowserDemo>
    <div className="layout-topaside">
      <div className="layout-header">
        <div className="layout-wrapper">
          <div className="layout-logo"></div>
          <Menu theme="dark" mode="horizontal"
            defaultSelectedKeys={['2']} style={{lineHeight: '64px'}}>
            <Menu.Item key="1">Navigation 1</Menu.Item>
            <Menu.Item key="2">Navigation 2</Menu.Item>
            <Menu.Item key="3">Navigation 3</Menu.Item>
          </Menu>
        </div>
      </div>
      <div className="layout-subheader">
        <div className="layout-wrapper">
          <Menu mode="horizontal"
            defaultSelectedKeys={['1']} style={{marginLeft: 124}}>
            <Menu.Item key="1">Second nav</Menu.Item>
            <Menu.Item key="2">Second nav</Menu.Item>
            <Menu.Item key="3">Second nav</Menu.Item>
          </Menu>
        </div>
      </div>
      <div className="layout-wrapper">
        <Breadcrumb>
          <Breadcrumb.Item>Home</Breadcrumb.Item>
          <Breadcrumb.Item>App list</Breadcrumb.Item>
          <Breadcrumb.Item>Any app</Breadcrumb.Item>
        </Breadcrumb>
        <div className="layout-container">
          <aside className="layout-sider">
            <Menu mode="inline" defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']}>
              <SubMenu key="sub1" title={<span><Icon type="user" />Navigation 1</span>}>
                <Menu.Item key="1">item 1</Menu.Item>
                <Menu.Item key="2">item 2</Menu.Item>
                <Menu.Item key="3">item 3</Menu.Item>
                <Menu.Item key="4">item 4</Menu.Item>
              </SubMenu>
              <SubMenu key="sub2" title={<span><Icon type="laptop" />Navigation 2</span>}>
                <Menu.Item key="5">item 5</Menu.Item>
                <Menu.Item key="6">item 6</Menu.Item>
                <Menu.Item key="7">item 7</Menu.Item>
                <Menu.Item key="8">item 8</Menu.Item>
              </SubMenu>
              <SubMenu key="sub3" title={<span><Icon type="notification" />Navigation 3</span>}>
                <Menu.Item key="9">item 9</Menu.Item>
                <Menu.Item key="10">item 10</Menu.Item>
                <Menu.Item key="11">item 11</Menu.Item>
                <Menu.Item key="12">item 12</Menu.Item>
              </SubMenu>
            </Menu>
          </aside>
          <div className="layout-content">
            <div style={{ height: 240 }}>
              <div style={{clear: 'both'}}>Contents</div>
            </div>
          </div>
        </div>
        <div className="layout-footer">
          Ant Design all rights reserved © 2015 Created by Ant UED
        </div>
      </div>
    </div>
  </BrowserDemo>
, mountNode);
.layout-topaside {
  height: 100%;
}

.layout-topaside .layout-wrapper {
  padding: 0 50px;
}

.layout-topaside .layout-header {
  background: #404040;
  height: 64px;
}

.layout-topaside .layout-logo {
  width: 120px;
  height: 32px;
  background: #333;
  border-radius: 4px;
  margin: 16px 24px 16px 0;
  float: left;
}

.layout-topaside .layout-subheader {
  height: 48px;
  border-bottom: 1px solid #e9e9e9;
  background: #fff;
  margin-bottom: 12px;
}

.layout-topaside .layout-container {
  background: #fff;
  margin: 12px 0 0;
  position: relative;
  padding: 24px 0;
  overflow: hidden;
  border-radius: 4px;
}

.layout-topaside .layout-sider {
  width: 224px;
  float: left;
}

.layout-topaside .layout-content {
  border-left: 1px solid #e9e9e9;
  padding: 0 24px;
  overflow: auto;
  position: relative;
  left: -1px;
}

.layout-topaside .layout-footer {
  height: 64px;
  line-height: 64px;
  text-align: center;
  font-size: 12px;
  color: #999;
}
Home/App list/Any App/
Contents

Aside top level navigation

A left-right structure of page layouts is used to Aside navigation, Generally, the mainnav is placed on the left side of the page, and the secondary menu is placed on the top of the working area. Contents will adapt the layout to the viewing area to improve the horizontal space usage, while the layout of the whole page is not stable.

The level of the aisde navigation is scalable. The first, second, and third level navigations could be present more fluently and relevantly, and aside navigation can be fixed, allowing the user to quickly switch and spot the current position, improving the user experience. However, this navigation occupies some horizontal space of the contents.

import { Menu, Breadcrumb, Icon } from 'antd';
import BrowserDemo from 'site/theme/template/BrowserDemo';
const SubMenu = Menu.SubMenu;

ReactDOM.render(
  <BrowserDemo>
    <div className="layout-aside">
      <aside className="layout-sider">
        <div className="layout-logo"></div>
        <Menu mode="inline" theme="dark"
          defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']}>
          <SubMenu key="sub1" title={<span><Icon type="user" />Navigation 1</span>}>
            <Menu.Item key="1">item 1</Menu.Item>
            <Menu.Item key="2">item 2</Menu.Item>
            <Menu.Item key="3">item 3</Menu.Item>
            <Menu.Item key="4">item 4</Menu.Item>
          </SubMenu>
          <SubMenu key="sub2" title={<span><Icon type="laptop" />Navigation 2</span>}>
            <Menu.Item key="5">item 5</Menu.Item>
            <Menu.Item key="6">item 6</Menu.Item>
            <Menu.Item key="7">item 7</Menu.Item>
            <Menu.Item key="8">item 8</Menu.Item>
          </SubMenu>
          <SubMenu key="sub3" title={<span><Icon type="notification" />Navigation 3</span>}>
            <Menu.Item key="9">item 9</Menu.Item>
            <Menu.Item key="10">item 10</Menu.Item>
            <Menu.Item key="11">item 11</Menu.Item>
            <Menu.Item key="12">item 12</Menu.Item>
          </SubMenu>
        </Menu>
      </aside>
      <div className="layout-main">
        <div className="layout-header"></div>
        <div className="layout-container">
          <Breadcrumb>
            <Breadcrumb.Item>Home</Breadcrumb.Item>
            <Breadcrumb.Item>App list</Breadcrumb.Item>
            <Breadcrumb.Item>Any App</Breadcrumb.Item>
          </Breadcrumb>
          <div className="layout-content">
            <div style={{ height: 590 }}>
              Contents
            </div>
          </div>
        </div>
        <div className="layout-footer">
          Ant Design all rights reserved © 2015 Created by Ant UED
        </div>
      </div>
    </div>
  </BrowserDemo>
, mountNode);
.layout-aside {
  position: relative;
  min-height: 100%;
}

.layout-aside .layout-logo {
  height: 32px;
  background: #333;
  border-radius: 4px;
  margin: 16px 24px;
}

.layout-aside .layout-sider {
  width: 224px;
  background: #404040;
  position: absolute;
  overflow: auto;
  padding-bottom: 24px;
  height: 100%;
}

.layout-aside .layout-sider > .menu {
  margin-bottom: 20px;
}

.layout-aside .layout-header {
  background: #fff;
  height: 64px;
  border-bottom: 1px solid #e9e9e9;
}

.layout-aside .layout-main {
  margin-left: 224px;
}

.layout-aside .layout-container {
  margin: 12px 16px 24px;
}

.layout-aside .layout-content {
  background: #fff;
  padding: 24px;
  margin-top: 12px;
  border-radius: 4px;
}

.layout-aside .layout-footer {
  height: 64px;
  line-height: 64px;
  text-align: center;
  font-size: 12px;
  color: #999;
  background: #fff;
  border-top: 1px solid #e9e9e9;
  width: 100%;
}
  • xxx@example.com
  • |
  • Help Center
  • |
  • Custom Service/Complaint Center phone:400-826-7710

Generally, ceiling is used for cross system/applications, where you can put uniform login/help information on top of the page.

Background color of a ceiling is a dark color, height is 30px, and a light color foreground for the mainnav should be used.

import { Menu, Breadcrumb } from 'antd';
import BrowserDemo from 'site/theme/template/BrowserDemo';

ReactDOM.render(
  <BrowserDemo>
    <div className="layout-ceiling-demo">
      <div className="layout-ceiling">
        <div className="layout-wrapper">
          <ul className="right">
            <li>xxx@example.com</li>
            <li>|</li>
            <li>Help Center</li>
            <li>|</li>
            <li>Custom Service/Complaint Center phone:400-826-7710</li>
          </ul>
        </div>
      </div>
      <div className="layout-header">
        <div className="layout-wrapper">
          <div className="layout-logo"></div>
        </div>
      </div>
    </div>
  </BrowserDemo>
, mountNode);
.layout-ceiling-demo {
  height: 100%;
}

.layout-ceiling {
  font-size: 12px;
  height: 30px;
  line-height: 30px;
  background-color: #242736;
  color: #ddd;
}

.layout-ceiling .right {
  float: right;
}

.layout-ceiling ul li {
  display: inline-block;
  margin: 0 4px;
}

.layout-ceiling-demo .layout-wrapper {
  padding: 0 50px;
}

.layout-ceiling-demo .layout-header {
  background: #fff;
  height: 64px;
  border-bottom: 1px solid #e9e9e9;
}

.layout-ceiling-demo .layout-logo {
  width: 120px;
  height: 32px;
  background: #eee;
  border-radius: 4px;
  margin: 16px 24px 16px 0;
  float: left;
}
Home/App list/Any app/
Contents

This pattern is used when the horizontal space is limited. By default, Aside navigation is collapsed. You can click the button at the bottom to expand it.

import { Menu, Breadcrumb, Icon } from 'antd';
import BrowserDemo from 'site/theme/template/BrowserDemo';
const SubMenu = Menu.SubMenu;

const AsideCollapse = React.createClass({
  getInitialState() {
    return {
      collapse: true,
    };
  },
  onCollapseChange() {
    this.setState({
      collapse: !this.state.collapse,
    })
  },
  render() {
    const collapse = this.state.collapse;
    return (
      <div className={collapse ? "layout-aside layout-aside-collapse" : "layout-aside"}>
        <aside className="layout-sider">
          <div className="layout-logo"></div>
          <Menu mode="inline" theme="dark" defaultSelectedKeys={['user']}>
            <Menu.Item key="user">
              <Icon type="user" />
              {!collapse && <span className="nav-text">Navigation 1</span>}
            </Menu.Item>
            <Menu.Item key="setting">
              <Icon type="setting" />
              {!collapse && <span className="nav-text">Navigation 2</span>}
            </Menu.Item>
            <Menu.Item key="laptop">
              <Icon type="laptop" />
              {!collapse && <span className="nav-text">Navigation 3</span>}
            </Menu.Item>
            <Menu.Item key="notification">
              <Icon type="notification" />
              {!collapse && <span className="nav-text">Navigation 4</span>}
            </Menu.Item>
            <Menu.Item key="folder">
              <Icon type="folder" />
              {!collapse && <span className="nav-text">Navigation 5</span>}
            </Menu.Item>
          </Menu>
          <div className="aside-action" onClick={this.onCollapseChange}>
            {collapse ? <Icon type="right" /> : <Icon type="left" />}
          </div>
        </aside>
        <div className="layout-main">
          <div className="layout-header"></div>
          <div className="layout-container">
            <Breadcrumb>
              <Breadcrumb.Item>Home</Breadcrumb.Item>
              <Breadcrumb.Item>App list</Breadcrumb.Item>
              <Breadcrumb.Item>Any app</Breadcrumb.Item>
            </Breadcrumb>
            <div className="layout-content">
              <div style={{ height: 220 }}>
                Contents
              </div>
            </div>
          </div>
          <div className="layout-footer">
            Ant Design all rights reserved © 2015 Created by Ant UED
          </div>
        </div>
      </div>
    );
  },
});

ReactDOM.render(<BrowserDemo><AsideCollapse /></BrowserDemo>, mountNode);
.layout-aside {
  position: relative;
  min-height: 100%;
}

.layout-aside .layout-logo {
  height: 32px;
  background: #333;
  border-radius: 4px;
  margin: 16px 24px;
  transition: all .3s;
}

.layout-aside-collapse .layout-logo {
  width: 32px;
  margin: 16px;
  transition: all .3s;
}

.layout-aside .layout-sider {
  width: 224px;
  background: #404040;
  position: absolute;
  overflow: visible;
  padding-bottom: 24px;
  height: 100%;
  transition: all .3s;
}

.layout-aside-collapse .layout-sider {
  width: 64px;
  transition: all .3s;
}

.layout-aside .layout-sider > .menu {
  margin-bottom: 20px;
}

.layout-aside .layout-sider > .menu > .menu-item {
  margin: 16px 0;
}

.layout-aside .layout-sider > .menu > .menu-item .nav-text {
  vertical-align: baseline;
  display: inline-block;
}

.layout-aside .layout-sider > .menu > .menu-item > .anticon {
  transition: font-size .3s;
}

.layout-aside-collapse .layout-sider > .menu > .menu-item {
  transition: all 0s ease;
}

.layout-aside-collapse .layout-sider > .menu > .menu-item > .anticon {
  font-size: 16px;
  display: inline-block;
}

.layout-aside-collapse .layout-sider > .menu > .menu-item .nav-text {
  display: none;
}

.layout-aside-collapse .layout-sider > .menu > .menu-item:hover {
  background: #2db7f5;
  color: #fff;
  transition: all 0s ease;
}

.layout-aside-collapse .layout-sider > .menu > .menu-item:hover .nav-text {
  display: inline-block;
  vertical-align: top;
  background: #2db7f5;
  color: #fff;
  padding-right: 16px;
  border-radius: 0 5px 5px 0;
}

/* 实际使用中需要改成 position: fixed */
.layout-aside .aside-action {
  height: 42px;
  width: 224px;
  position: absolute;
  bottom: 0;
  background: #656565;
  color: #fff;
  text-align: center;
  line-height: 42px;
  cursor: pointer;
  transition: all .3s;
}

.layout-aside-collapse .aside-action {
  width: 64px;
  transition: all .3s;
}

.layout-aside .layout-header {
  background: #fff;
  height: 64px;
  border-bottom: 1px solid #e9e9e9;
}

.layout-aside .layout-main {
  margin-left: 224px;
  transition: all .3s;
}

.layout-aside-collapse .layout-main {
  margin-left: 64px;
  transition: all .3s;
}

.layout-aside .layout-container {
  margin: 12px 16px 24px;
}

.layout-aside .layout-content {
  background: #fff;
  padding: 24px;
  margin-top: 12px;
  border-radius: 4px;
}

.layout-aside .layout-footer {
  height: 64px;
  line-height: 64px;
  text-align: center;
  font-size: 12px;
  color: #999;
  background: #fff;
  border-top: 1px solid #e9e9e9;
  width: 100%;
}