Skip to content

✨ 布局 👌

1. 多栏布局

1.1 两栏布局

两栏布局是指页面分为左右两个区域,通常一侧为固定宽度的侧边栏,另一侧为自适应宽度的主内容区。

CSS2 实现

实现原理:

  • 侧边栏使用浮动定位
  • 主内容区通过 overflow: hidden 形成 BFC,实现宽度自适应

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>两栏布局示例</title>
    <style>
      .clearfix::after {
        content: "";
        display: block;
        clear: both;
      }

      .container {
        padding: 30px;
        border: 3px solid #333;
      }

      .aside {
        width: 300px;
        background: lightblue;
        float: left;
        margin-right: 20px;
        padding: 20px;
        box-sizing: border-box;
      }

      .main {
        /* 关键代码:使得main形成BFC,宽度自适应 */
        overflow: hidden;
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }
    </style>
  </head>
  <body>
    <div class="container clearfix">
      <aside class="aside">
        <h3>侧边栏</h3>
        <p>固定宽度 300px</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>自适应宽度,通过 BFC 实现</p>
        <p>当窗口大小改变时,主内容区会自动调整宽度</p>
      </div>
    </div>
  </body>
</html>

CSS3 实现

CSS3 Flexbox 实现两栏布局

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Flexbox 两栏布局</title>
    <style>
      .container {
        padding: 30px;
        border: 3px solid #333;
        display: flex; /* 使用 Flexbox */
        gap: 20px; /* 设置间距 */
      }

      .aside {
        width: 300px; /* 固定宽度 */
        background: lightblue;
        padding: 20px;
        box-sizing: border-box;
        flex-shrink: 0; /* 防止收缩 */
      }

      .main {
        flex: 1; /* 自动占据剩余空间 */
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <aside class="aside">
        <h3>侧边栏</h3>
        <p>固定宽度 300px</p>
        <p>使用 flex-shrink: 0 防止收缩</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>使用 flex: 1 自动占据剩余空间</p>
        <p>响应式友好,无需清除浮动</p>
      </div>
    </div>
  </body>
</html>
CSS Grid 实现两栏布局

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CSS Grid 两栏布局</title>
    <style>
      .container {
        padding: 30px;
        border: 3px solid #333;
        display: grid; /* 使用 CSS Grid */
        grid-template-columns: 300px 1fr; /* 固定宽度 + 自适应 */
        gap: 20px; /* 设置间距 */
      }

      .aside {
        background: lightblue;
        padding: 20px;
        box-sizing: border-box;
      }

      .main {
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <aside class="aside">
        <h3>侧边栏</h3>
        <p>通过 grid-template-columns 控制宽度</p>
        <p>300px 固定宽度</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>1fr 表示占据剩余空间</p>
        <p>Grid 布局语义更清晰</p>
      </div>
    </div>
  </body>
</html>

1.2 三栏布局

三栏布局是指页面分为左、中、右三个区域,通常左右两侧为固定宽度,中间为自适应宽度。

CSS2 实现

实现原理:

  • 左右侧边栏使用浮动定位
  • 中间主内容区通过 overflow: hidden 形成 BFC,实现宽度自适应

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>三栏布局示例</title>
    <style>
      .clearfix::after {
        content: "";
        display: block;
        clear: both;
      }

      .container {
        padding: 30px;
        border: 3px solid #333;
      }

      .left {
        width: 200px;
        background: lightcoral;
        float: left;
        margin-right: 20px;
        padding: 20px;
        box-sizing: border-box;
      }

      .right {
        width: 200px;
        background: lightgreen;
        float: right;
        margin-left: 20px;
        padding: 20px;
        box-sizing: border-box;
      }

      .main {
        /* 关键代码:使得main形成BFC,宽度自适应 */
        overflow: hidden;
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }
    </style>
  </head>
  <body>
    <div class="container clearfix">
      <aside class="left">
        <h4>左侧栏</h4>
        <p>固定宽度 200px</p>
      </aside>
      <aside class="right">
        <h4>右侧栏</h4>
        <p>固定宽度 200px</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>自适应宽度,通过 BFC 实现</p>
        <p>左右两侧固定宽度,中间区域自动调整</p>
      </div>
    </div>
  </body>
</html>

CSS3 实现

CSS3 Flexbox 实现三栏布局

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Flexbox 三栏布局</title>
    <style>
      .container {
        padding: 30px;
        border: 3px solid #333;
        display: flex; /* 使用 Flexbox */
        gap: 20px; /* 设置间距 */
      }

      .left {
        width: 200px; /* 固定宽度 */
        background: lightcoral;
        padding: 20px;
        box-sizing: border-box;
        flex-shrink: 0; /* 防止收缩 */
      }

      .main {
        flex: 1; /* 自动占据剩余空间 */
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }

      .right {
        width: 200px; /* 固定宽度 */
        background: lightgreen;
        padding: 20px;
        box-sizing: border-box;
        flex-shrink: 0; /* 防止收缩 */
      }
    </style>
  </head>
  <body>
    <div class="container">
      <aside class="left">
        <h4>左侧栏</h4>
        <p>固定宽度 200px</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>flex: 1 自动占据剩余空间</p>
        <p>左右两侧固定,中间自适应</p>
      </div>
      <aside class="right">
        <h4>右侧栏</h4>
        <p>固定宽度 200px</p>
      </aside>
    </div>
  </body>
</html>
CSS Grid 实现三栏布局

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CSS Grid 三栏布局</title>
    <style>
      .container {
        padding: 30px;
        border: 3px solid #333;
        display: grid; /* 使用 CSS Grid */
        grid-template-columns: 200px 1fr 200px; /* 固定 + 自适应 + 固定 */
        gap: 20px; /* 设置间距 */
      }

      .left {
        background: lightcoral;
        padding: 20px;
        box-sizing: border-box;
      }

      .main {
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }

      .right {
        background: lightgreen;
        padding: 20px;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <aside class="left">
        <h4>左侧栏</h4>
        <p>200px 固定宽度</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>1fr 占据剩余空间</p>
        <p>Grid 布局更直观</p>
      </div>
      <aside class="right">
        <h4>右侧栏</h4>
        <p>200px 固定宽度</p>
      </aside>
    </div>
  </body>
</html>

1.3 多栏布局方案对比

方案优势劣势适用场景
浮动 + BFC兼容性好,支持所有浏览器需要清除浮动,代码复杂传统项目,兼容性要求高
Flexbox语法简洁,响应式友好,等高天然支持IE10+ 支持现代项目,一维布局
CSS Grid功能强大,二维布局,语义清晰IE11+ 支持(需前缀)复杂布局,现代项目

2. 等高布局

等高布局是指多个并排的容器具有相同的高度,无论其内容多少。

2.1 实现方式

  1. CSS3 弹性盒(推荐)

    • 使用 display: flex
    • 子元素自动等高
  2. JavaScript 控制

    • 动态计算最高元素的高度
    • 设置所有元素为相同高度
  3. 伪等高布局

    • 使用 padding-bottommargin-bottom 的负值
    • 配合父容器的 overflow: hidden

2.2 伪等高布局示例

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>伪等高布局</title>
    <style>
      .container {
        overflow: hidden; /* 关键:隐藏超出部分 */
        border: 3px solid #333;
        padding: 20px;
      }

      .clearfix::after {
        content: "";
        display: block;
        clear: both;
      }

      .aside {
        width: 300px;
        background: lightblue;
        float: left;
        margin-right: 20px;
        padding: 20px;
        box-sizing: border-box;
        /* 关键代码:伪等高实现 */
        padding-bottom: 9999px;
        margin-bottom: -9999px;
      }

      .main {
        overflow: hidden;
        background: #f9f9f9;
        padding: 20px;
        /* 关键代码:伪等高实现 */
        padding-bottom: 9999px;
        margin-bottom: -9999px;
      }
    </style>
  </head>
  <body>
    <div class="container clearfix">
      <aside class="aside">
        <h3>侧边栏</h3>
        <p>内容较少</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>这里有更多的内容</p>
        <p>无论哪一侧内容更多</p>
        <p>两个区域都会保持相同的高度</p>
        <p>这就是伪等高布局的效果</p>
      </div>
    </div>
  </body>
</html>

2.3 Flexbox 等高布局

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Flexbox 等高布局</title>
    <style>
      .container {
        display: flex; /* 关键:使用弹性布局 */
        gap: 20px;
        padding: 20px;
        border: 3px solid #333;
      }

      .aside {
        width: 300px;
        background: lightblue;
        padding: 20px;
        box-sizing: border-box;
      }

      .main {
        flex: 1; /* 关键:自动占据剩余空间 */
        background: #f9f9f9;
        padding: 20px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <aside class="aside">
        <h3>侧边栏</h3>
        <p>内容较少</p>
      </aside>
      <div class="main">
        <h3>主内容区</h3>
        <p>这里有更多的内容</p>
        <p>使用 Flexbox 实现等高</p>
        <p>代码更简洁,兼容性更好</p>
        <p>是现代布局的推荐方案</p>
      </div>
    </div>
  </body>
</html>

3. 元素书写顺序优化

3.1 问题描述

在传统的浮动布局中,侧边栏需要写在主内容区之前,这不利于 SEO,因为搜索引擎更重视页面前面的内容。

3.2 解决方案:绝对定位

使用绝对定位可以让主内容区的 HTML 代码写在前面,同时实现理想的视觉布局。

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>优化元素书写顺序</title>
    <style>
      .container {
        padding: 30px;
        border: 3px solid #333;
        position: relative; /* 为绝对定位提供包含块 */
      }

      .left {
        width: 300px;
        background: lightblue;
        /* 关键代码:使用绝对定位 */
        position: absolute;
        left: 30px; /* 考虑父元素的 padding */
        top: 30px;
        padding: 20px;
        box-sizing: border-box;
      }

      .right {
        width: 300px;
        background: lightgreen;
        /* 关键代码:使用绝对定位 */
        position: absolute;
        right: 30px; /* 考虑父元素的 padding */
        top: 30px;
        padding: 20px;
        box-sizing: border-box;
      }

      .main {
        /* 关键代码:预留出侧边栏的宽度 */
        margin: 0 320px; /* 左右各预留 300px + 20px 间距 */
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <!-- 主内容区写在前面,有利于 SEO -->
      <div class="main">
        <h3>主内容区</h3>
        <p>这是最重要的内容,写在 HTML 的前面</p>
        <p>有利于搜索引擎优化(SEO)</p>
        <p>通过绝对定位实现侧边栏的布局</p>
      </div>

      <!-- 侧边栏写在后面 -->
      <aside class="left">
        <h4>左侧栏</h4>
        <p>次要内容</p>
      </aside>

      <aside class="right">
        <h4>右侧栏</h4>
        <p>次要内容</p>
      </aside>
    </div>
  </body>
</html>

3.3 CSS3 现代解决方案

3.3.1 使用 Flexbox 实现

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Flexbox 优化元素顺序</title>
    <style>
      .container {
        padding: 30px;
        border: 3px solid #333;
        display: flex; /* 使用 Flexbox */
        gap: 20px; /* 设置间距 */
      }

      .left {
        width: 300px;
        background: lightblue;
        padding: 20px;
        box-sizing: border-box;
        order: 1; /* 控制显示顺序:左侧栏 */
      }

      .main {
        flex: 1; /* 自动占据剩余空间 */
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
        order: 2; /* 控制显示顺序:主内容区 */
      }

      .right {
        width: 300px;
        background: lightgreen;
        padding: 20px;
        box-sizing: border-box;
        order: 3; /* 控制显示顺序:右侧栏 */
      }
    </style>
  </head>
  <body>
    <div class="container">
      <!-- 主内容区写在前面,有利于 SEO -->
      <div class="main">
        <h3>主内容区</h3>
        <p>这是最重要的内容,写在 HTML 的前面</p>
        <p>有利于搜索引擎优化(SEO)</p>
        <p>通过 Flexbox 的 order 属性控制显示顺序</p>
      </div>

      <!-- 侧边栏写在后面 -->
      <aside class="left">
        <h4>左侧栏</h4>
        <p>次要内容</p>
      </aside>

      <aside class="right">
        <h4>右侧栏</h4>
        <p>次要内容</p>
      </aside>
    </div>
  </body>
</html>

3.3.2 使用 CSS Grid 实现

代码示例:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CSS Grid 优化元素顺序</title>
    <style>
      .container {
        padding: 30px;
        border: 3px solid #333;
        display: grid; /* 使用 CSS Grid */
        grid-template-columns: 300px 1fr 300px; /* 左侧栏 主内容 右侧栏 */
        grid-template-areas: "left main right"; /* 定义网格区域 */
        gap: 20px; /* 设置间距 */
      }

      .left {
        grid-area: left; /* 指定网格区域 */
        background: lightblue;
        padding: 20px;
        box-sizing: border-box;
      }

      .main {
        grid-area: main; /* 指定网格区域 */
        border: 2px solid #666;
        padding: 20px;
        background: #f9f9f9;
      }

      .right {
        grid-area: right; /* 指定网格区域 */
        background: lightgreen;
        padding: 20px;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <!-- 主内容区写在前面,有利于 SEO -->
      <div class="main">
        <h3>主内容区</h3>
        <p>这是最重要的内容,写在 HTML 的前面</p>
        <p>有利于搜索引擎优化(SEO)</p>
        <p>通过 CSS Grid 的 grid-area 属性控制布局位置</p>
      </div>

      <!-- 侧边栏写在后面 -->
      <aside class="left">
        <h4>左侧栏</h4>
        <p>次要内容</p>
      </aside>

      <aside class="right">
        <h4>右侧栏</h4>
        <p>次要内容</p>
      </aside>
    </div>
  </body>
</html>

3.4 方案对比

方案优势劣势适用场景
绝对定位兼容性好,精确控制位置需要手动计算,高度适应性差传统项目,固定布局
Flexbox灵活,自适应,易于响应式IE10+ 支持现代项目,一维布局
CSS Grid强大的二维布局能力,语义清晰IE11+ 支持(需前缀)复杂布局,现代项目

3.5 最佳实践

  1. 现代项目推荐使用 Flexbox 或 Grid
  2. 移动端优先考虑 Flexbox
  3. 复杂二维布局使用 Grid
  4. 需要兼容老版本浏览器时使用绝对定位

4. 后台页面布局

后台管理系统通常需要充满整个屏幕,并支持分区域滚动的布局方式。

4.1 布局特点

  • 覆盖整个视口(100vw × 100vh)
  • 头部固定,内容区域可滚动
  • 左侧导航固定宽度,主内容区自适应
  • 各区域独立滚动

4.2 实现方案

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>后台页面布局</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      .app {
        /* 关键代码:覆盖整个屏幕 */
        position: fixed;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        font-family: Arial, sans-serif;
      }

      .header {
        height: 60px;
        background: #2c3e50;
        color: white;
        /* 使用绝对定位固定在顶部 */
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        display: flex;
        align-items: center;
        padding: 0 20px;
        z-index: 1000;
      }

      .container {
        width: 100%;
        height: 100%;
        /* 预留出 header 的高度 */
        padding-top: 60px;
        display: flex;
      }

      .sidebar {
        width: 250px;
        background: #34495e;
        color: white;
        padding: 20px;
        /* 关键代码:独立滚动 */
        overflow-y: auto;
        flex-shrink: 0; /* 防止收缩 */
      }

      .main {
        flex: 1; /* 占据剩余空间 */
        background: #ecf0f1;
        padding: 20px;
        /* 关键代码:独立滚动 */
        overflow-y: auto;
      }

      .nav-item {
        padding: 10px 0;
        border-bottom: 1px solid #2c3e50;
        cursor: pointer;
      }

      .nav-item:hover {
        background: #2c3e50;
      }

      .content-section {
        background: white;
        margin-bottom: 20px;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
      }
    </style>
  </head>
  <body>
    <div class="app">
      <!-- 固定头部 -->
      <header class="header">
        <h1>后台管理系统</h1>
      </header>

      <!-- 主体容器 -->
      <div class="container">
        <!-- 左侧导航 -->
        <aside class="sidebar">
          <h3>导航菜单</h3>
          <div class="nav-item">用户管理</div>
          <div class="nav-item">内容管理</div>
          <div class="nav-item">系统设置</div>
          <div class="nav-item">数据统计</div>
          <div class="nav-item">权限管理</div>
          <div class="nav-item">日志查看</div>
          <div class="nav-item">备份恢复</div>
          <div class="nav-item">插件管理</div>
          <div class="nav-item">主题设置</div>
          <div class="nav-item">帮助文档</div>
        </aside>

        <!-- 主内容区 -->
        <main class="main">
          <div class="content-section">
            <h2>欢迎使用后台管理系统</h2>
            <p>这是一个典型的后台页面布局示例</p>
          </div>

          <div class="content-section">
            <h3>布局特点</h3>
            <ul>
              <li>固定头部,始终可见</li>
              <li>左侧导航固定宽度</li>
              <li>主内容区自适应宽度</li>
              <li>各区域独立滚动</li>
              <li>充满整个视口</li>
            </ul>
          </div>

          <div class="content-section">
            <h3>技术要点</h3>
            <ul>
              <li>使用 <code>position: fixed</code> 覆盖整个屏幕</li>
              <li>头部使用绝对定位固定</li>
              <li>容器使用 <code>padding-top</code> 预留头部空间</li>
              <li>使用 Flexbox 实现左右布局</li>
              <li>各区域设置 <code>overflow-y: auto</code> 独立滚动</li>
            </ul>
          </div>

          <!-- 更多内容用于测试滚动 -->
          <div class="content-section">
            <h3>滚动测试内容</h3>
            <p>这里可以放置大量内容来测试滚动效果...</p>
            <p>主内容区域可以独立滚动</p>
            <p>而头部和侧边栏保持固定</p>
          </div>
        </main>
      </div>
    </div>
  </body>
</html>