css两边固定中间自适应布局

5,013 阅读9分钟

三栏布局是一种常见的网页布局方案,最常见的需求就是两边固定,中间自适应效果,而这种布局有很多种不同的实现方案,在不同的需求和兼容性要求下适用性各不相同,下面来看一下常见的几种实现方式和它们的特点。

普通浮动布局

流体布局非常简单,就是利用元素浮动的特性来实现布局,实现起来其实并不难

<style>
       .container>div{
           height: 200px;
       }
       .left {
           float: left;
           width: 300px;
           background: red;
       }
       .right {
           float: right;
           width: 300px;
           background: blue;
       }
       .center {
       	overflow: hidden;
           background: yellow;
       }
   </style>
   <div class="container">
       <div class="left"></div>
       <div class="right"></div>
       <div class="center">
           <h1>浮动布局</h1>
       </div>
   </div>


这种布局主要是控制元素浮动来实现的,要注意的一点就是中间元素要创建BFC(关于BFC的相关内容后面文章会分析),否则一旦高度变化就会无法正常工作。这种布局的特点就是浮动对旧浏览器兼容性好,缺点就是主体内容需要放到最后加载,当页面元素较多时候可能会影响体验,于是有了下面两种非常经典的改进方案。

圣杯布局

圣杯布局并不是因为长得像杯子,在西方,圣杯是表达“渴求之物”的意思,题外话,下面回来看它的实现。首先我们的目的是要实现中间部分先加载,所以html结构大体上是确定的,接下来一步一步来看圣杯布局的形成。

<div class="container">
       <div class="center">
           <h1>圣杯布局</h1>
       </div>
       <div class="left"></div>
       <div class="right"></div>
   </div>

1.给元素添加左浮动效果,代码和效果如下

.container>div {
          height: 200px;
      }
      .center {
          float: left;
          width: 100%;
          background: yellow;
      }
      .left {
          float: left;
          width: 300px;
          background: red;
      }
      .right {
          float: left;
          width: 300px;
          background: blue;
      }


此时肯定是不符合预期的,所以要进行下一步调整。

2.这一步是重点,为左右元素设置-margin值,其中需要设置左边元素左边距为负的中间盒子的宽度,也就是.left {margin-left:-100%;},需要设置右边元素左边距为负的自己的宽度,也就是.right {margin-left:-300px;},此时效果如图

看上去似乎实现了,不过中间元素此时是被压在下面的,所以还需要进一步处理。

3.要想把左右元素放在中间元素两边,就需要让两边有边距,所以首先要给父元素加一个内边距,即添加.container {padding: 0 300px;}显示效果如下。此时两边已经产生边距,不过两边元素还是在上中间元素面显示。

4.最后一步,给两边的元素加相对定位,然后把它们定位到两边空位处,即可实现最终效果,最终全部代码和显示效果如下

<style>
       .container {
           padding: 0 300px;
       }
       .container>div {
           height: 200px;
       }
       .center {
           float: left;
           width: 100%;
           background: yellow;
       }
       .left {
           float: left;
           width: 300px;
           background: red;
           margin-left: -100%;
           position: relative;
           left: -300px;
       }
       .right {
           float: left;
           width: 300px;
           background: blue;
           margin-left: -300px;
           position: relative;
           right: -300px;
       }
   </style>
   <div class="container">
       <div class="center">
           <h1>圣杯布局</h1>
       </div>
       <div class="left"></div>
       <div class="right"></div>
   </div>


这样就实现了圣杯布局,圣杯布局保持了与普通浮动布局同样的兼容性,最大的优点是可以实现中间部分优先加载,缺点就是处理复杂,而且当中间元素小于两侧元素时候会出现变形,响应效果相对差一点。

双飞翼布局

除了圣杯布局,还有另一种和它原理类似的解决方案,同样可以处理浮动布局的加载问题,这种实现方案来自淘宝的UED,叫做双飞翼布局。

双飞翼布局的html结构和圣杯布局有一点小差别,就是中间元素外面多了一层容器,代码如下

<div class="container">
       <div class="center-container">
           <div class="center">
               <h1>双飞翼布局</h1>
           </div>
       </div>
       <div class="left"></div>
       <div class="right"></div>
   </div>

前两步的样式设置和和圣杯布局是相同的,元素左浮动,两侧-margin,最终产生了和上面相同的元素被遮盖的情况。

接下来,也是双飞翼布局的特点所在,由于实际中间元素是放在一个容器里面的,我们可以给内部元素设置外边距,这样就可以让出两边的位置,两边元素也无需重定位即可完成布局,完整代码和显示效果如下

<style>
       .container div {
           height: 200px;
       }
       .center-container {
           float: left;
           width: 100%;
           height: 100px;
           background: yellow;
       }
       .center {
           margin: 0 300px;
       }
       .left {
           background: red;
           float: left;
           width: 300px;
           margin-left: -100%;
       }
       .right {
           background: blue;
           float: left;
           width: 300px;
           margin-left: -300px;
       }
   </style>
   <div class="container">
       <div class="center-container">
           <div class="center">
               <h1>双飞翼布局</h1>
           </div>
       </div>
       <div class="left"></div>
       <div class="right"></div>
   </div>

双飞翼布局相比圣杯布局更简洁,多使用了一个div,不过简洁性和响应能力上要比圣杯布局好。

圣杯布局和双飞翼布局都是在浮动布局时代的比较经典的布局方式,对旧的浏览器有很好的兼容性。不过事实上,现代浏览器已经大量普及,需要适配旧浏览器的场景已经开始变少,加上移动端开发越来越盛行,于是有了比较新的布局方式。

flex布局

flex是css3提供的一种新的布局方式,这种布局的产生就是为了实现自适应布局,它是随着移动互联网时代产生而引进的,我们来看一下使用flex来实现三栏布局的代码

<style>
       .container {
           display: flex;
       }
       .container>div {
           height: 200px;
       }
       .left {
           width: 300px;
           background: red;
       }
       .center {
           flex: 1;
           background: yellow;
       }
       .right {
           width: 300px;
           background: blue;
       }
   </style>
   <div class="container">
       <div class="left"></div>
       <div class="center">
           <h1>flexbox</h1>
       </div>
       <div class="right"></div>
   </div>


就是这样简单,把外层容器显示属性设置成flex,里面只要自适应部分flex设置为1,就可以实现自适应效果了。使用flex布局的代码特别简洁,也是实现自适应布局的最佳方案,唯一的问题就是旧浏览器不兼容这一布局方式。不过其实如上面所说,其实现在需要适配旧浏览器的场景越来越少了,尤其是移动开发,flex可以完全放心使用。

table布局

table布局其实我们已经很熟悉了,就是表格布局,那么表格布局是这样实现三栏自适应的效果呢?其实不难理解,就是把三列都看做是表格,控制表格的显示情况即可,实现如下

<style>
       .container {
           width: 100%;
           display: table;
           height: 200px;
       }
       .container>div {
           display: table-cell;
       }
       .left {
           width: 300px;
           background: red;
       }
       .center {
           background: yellow;
       }
       .right {
           width: 300px;
           background: blue;
       }
   </style>
   <div class="container">
       <div class="left"></div>
       <div class="center">
           <h1>表格布局</h1>
       </div>
       <div class="right"></div>
   </div>


把外层容器设置成table,里面设置为table-cell,就可以很容易地实现布局需求。这种布局方式兼容性还特别好,因为表格是兼容旧浏览器的,虽然遭受很多诟病,但是真的可以解决问题。当然这种布局有缺点,缺点就是不灵活,边框设置、高度设置等等都有很大受限。

绝对定位布局

这种布局方式很明显了,利用绝对定位,实现起来非常容易

<style>
       .container>div {
           position: absolute;
           height: 200px;
       }
       .left {
           left: 0;
           width: 300px;
           background: red;
       }
       .center {
           left: 300px;
           right: 300px;
           background: yellow;
       }
       .right {
           right: 0;
           width: 300px;
           background: blue;
       }
   </style>
   <div class="container">
       <div class="left"></div>
       <div class="center">
           <h1>绝对定位布局</h1>
       </div>
       <div class="right"></div>
   </div>


绝对定位布局,很容易,效率也很高,不过实际开发中很少使用,原因也很简单,绝对定位的元素是脱离文档流的,可维护性会受限。

网格布局

最后再来看一个比较新的东西,网格布局,这个布局是新的css标准下的特性,在响应式布局大行其道的移动互联网时代,bootstrap之类的是对栅格化布局框架非常流行,而网格布局,就是对栅格布局的标准化实现,下面是用网格布局实现代码和效果

<style>
       .container {
           display: grid;
           width: 100%;
           grid-template-rows: 200px;
           grid-template-columns: 300px auto 300px;
       }
       .left {
           background: red;
       }
       .center {
           background: yellow;
       }
       .right {
           background: blue;
       }
   </style>
   <div class="container">
       <div class="left"></div>
       <div class="center">
           <h1>网格布局</h1>
       </div>
       <div class="right"></div>
   </div>


可以很明显地看出来,这种布局方式特别清晰,把整个页面设置成网格,设置网格内元素占的行和列,可以很容易实现想要的自适应效果。这种布局方式产生的时间相对较短,最大的问题是浏览器兼容性,不过新技术至少是要了解的。


以上就是对两边固定,中间自适应的布局的多种方式实现,实际使用时候,首先要考虑浏览器兼容情况,然后根据具体的业务中对元素宽高的要求限制,选择一种合适的布局方式来解决问题。