实现CSS等高布局的5个实例

等高布局常用在两列或多列布局中。

本文将以实例的方式,介绍几种等高布局的实现。



问题

我们以下面第一个三列结构为例。正常情况下,元素的高度是由内容决定的,我们可以看到两边只有一行,而中间有三行,所以中间的高度要大于两边。

而我们期待的效果如同第二个三列结构,两边的列能和中间一列一样高。而且不管任何一列内容是最多时,三列总是一样高的。

<style>
  .container {
    text-align: center;
  }
  
  .left, .right {
    width: 25%;
    float: left;
    background: green;
  }
  
  .main {
    float: left;
    width: 50%;
    background: black;
    color: white;
  }
  
  .clearfix {
    clear: both;
  }

  .equal-height {
    display: table;
    table-layout: fixed;
    width: 100%;
  }

  .equal-height > div {
    display: table-cell;
    float: none;
  }
</style>

<p>存在的问题</p>
<div class="container">
  <div class="left">这是一行内容</div>
  <div class="main">
    这是多行内容
    <br>这是多行内容
    <br>这是多行内容
  </div>
  <div class="right">这是一行内容</div>
</div>

<div class="clearfix"></div>

<p>希望达到的效果</p>
<div class="container equal-height">
  <div class="left">这是一行内容</div>
  <div class="main">
    这是多行内容
    <br>这是多行内容
    <br>这是多行内容
  </div>
  <div class="right">这是一行内容</div>
</div>

尝试一下 »


实例1,使用 display: table

<style>
  .container {
    text-align: center;
  }
  
  .left, .right {
    width: 25%;
    float: left;
    background: green;
  }
  
  .main {
    float: left;
    width: 50%;
    background: black;
    color: white;
  }
  
  .equal-height {
    display: table;
    table-layout: fixed;
    width: 100%;
  }

  .equal-height > div {
    display: table-cell;
    float: none;
  }
</style>

<div class="container equal-height">
  <div class="left">这是一行内容</div>
  <div class="main">
    这是多行内容
    <br>这是多行内容
    <br>这是多行内容
  </div>
  <div class="right">这是一行内容</div>
</div>

尝试一下 »

实例详解

  1. 外层容器通过 display: table 设置为表格。
  2. 内层的通过 display: table-cell 设置为表格单元。
  3. 内外组成一个表格结构,而表格单元是天生等高的,因此实现了等高效果。

优点

  1. 实现简单。

缺点

  1. 内层元素展示为 table-cell,margin会失效,只能在 .container 设置 border-spacing 为所有元素设置间隔,或内部增加一层来设置 margin

浏览器兼容性

IE / Edge Chrome Firefox Safari Opera
8 4 2 3.1 9

实例2,使用负 margin

<style>
  .container {
    text-align: center;
  }

  .left,
  .right {
    width: 25%;
    float: left;
    background: green;
  }

  .main {
    float: left;
    width: 50%;
    background: black;
    color: white;
  }

  .equal-height {
    overflow: hidden;
  }

  .equal-height > div {
    padding-bottom: 9999px;
    margin-bottom: -9999px;
  }
</style>

<div class="container equal-height">
  <div class="left">
    这是一行内容
  </div>
  <div class="main">
    这是多行内容
    <br>这是多行内容
    <br>这是多行内容
  </div>
  <div class="right">
    这是一行内容
  </div>
</div>

尝试一下 »

案例详解

  1. 子元素设置了 padding-bottom: 9999pxmargin-bottom: -9999px,使自身盒子高度达到9999px,但是内部的内容高度仍然不变
  2. 父容器设置了 overflow: hidden 隐藏掉超出的高度,使显示出来的子元素一样高。

优点

  1. 实现简单。

缺点

  1. 为子元素增加底部边框将不会显示,因为超出被隐藏了。

浏览器兼容性

所有主流浏览器都支持。


实例3,使用绝对定位

<style>
  .container {
    text-align: center;
  }

  .left,
  .right {
    width: 25%;
    float: left;
    background: green;
  }

  .main {
    float: left;
    width: 50%;
    background: black;
    color: white;
  }

  .equal-height {
    position: relative;
  }

  .equal-height .left,
  .equal-height .right {
    position: absolute;
    top: 0;
    bottom: 0; /* 将高度拉到和中间一样高 */
    float: none;
  }

  .equal-height .left {
    left: 0;
  }

  .equal-height .right {
    right: 0;
  }

  .equal-height .main {
    margin: 0 25%;
    float: none;
  }
</style>

<div class="container equal-height">
  <div class="left">
    这是一行内容
  </div>
  <div class="main">
    这是多行内容
    <br>这是多行内容
    <br>这是多行内容
  </div>
  <div class="right">
    这是一行内容
  </div>
</div>

尝试一下 »

实例详解

  1. 中间内容撑起父容器的高度。
  2. 左右两边是绝对定位的,通过设置 top: 0; bottom: 0;,将高度提高到和父容器一样高。

优点

无特别优点。

缺点

  1. 两边内容高度需低于中间内容,否则会超出父容器。

浏览器兼容性

所有主流浏览器都支持。


实例4,使用 flex

<style>
  .container {
    text-align: center;
  }

  .left,
  .right {
    width: 25%;
    float: left;
    background: green;
  }

  .main {
    float: left;
    width: 50%;
    background: black;
    color: white;
  }

  .equal-height {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    text-align: center;
  }

  .equal-height .left,
  .equal-height .right {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 25%;
    flex: 0 0 25%; /* 不缩小,不扩大,基础宽度为25% */
    background: green;
  }

  .equal-height .main {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 50%;
    flex: 0 0 50%; /* 不缩小,不扩大,基础宽度为50% */
    background: black;
    color: white;
  }
</style>

<div class="container equal-height">
  <div class="left">
    这是一行内容
  </div>
  <div class="main">
    这是多行内容
    <br>这是多行内容
    <br>这是多行内容
  </div>
  <div class="right">
    这是一行内容
  </div>
</div>

尝试一下 »

实例详解

  1. 父容器通过 display: flex 设置为 flex 布局。
  2. 子元素通过 flex: 0 0 25% 设置不缩小,不扩大的固定宽度,和原始宽度匹配。
  3. flex 布局的子元素天生等高。

优点

  1. 实现简单。
  2. 可利用 flex 布局的优势,实现更多效果。

缺点

  1. 需IE10及以上才支持。

浏览器兼容性

IE / Edge Chrome Firefox Safari Opera
11
10 -ms-
20
4 -webkit-
27
2 -moz-
6
3.1 -webkit-
12.1

实例5,使用边框模拟

<style>
  .container {
    position: relative;
    background: green;
    text-align: center;
  }

  .main {
    border-left: 100px solid green; /* 同左边元素的宽度 */
    border-right: 100px solid green; /* 同右边元素的宽度 */
    background: black;
    color: white;
  }

  .left {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
  }

  .right {
    position: absolute;
    top: 0;
    right: 0;
    width: 100px;
  }
</style>

<div class="container">
  <div class="left">
    这是一行内容
  </div>
  <div class="main">
    这是多行内容
    <br>这是多行内容
    <br>这是多行内容
  </div>
  <div class="right">
    这是一行内容
  </div>
</div>

尝试一下 »

实例详解

  1. 左右两边是绝对定位的,固定宽度为 100px
  2. 中间设置左右边框为 100px,刚好展示在左右两边的下面,看起来象是两边的背景。

优点

无特别优点。

缺点

  1. 这种实现是伪等高,只是视觉上是等高,实际左右两边的高度是不变。
  2. 左右两边需是固定宽度,才能算出中间的边框宽度。

浏览器兼容性

所有主流浏览器都支持。


总结

以上都是常见的CSS实现等高的方法,如果布局是两列,四列,甚至是更多列,实现原理是一样的,可根据情况进行调整。

有时我们是实现了布局再实现等高的,两者相互作用会发现有一些 CSS 冲突,这时推荐使用 JS 来实现等高。