css:如何实现左右定宽,中间自适应布局

2,906 阅读3分钟

这是我参与更文挑战的第5天,活动详情查看: 更文挑战

前述

今天看到一个css题目,说你能用几种方式来实现css左右定宽,中间自适应布局?恰好好久没写布局了,今天通过几种布局方式巩固一下,加深印象。

我下面分别使用圣杯布局双飞翼布局Flex布局绝对定位布局实现

圣杯布局

圣杯布局是一种三列左右栏固定中间栏边框自适应的网页布局

特点:
采用float浮动
三列布局,中间宽度自适应,两边定宽;
中间元素要在html结构中处于开头;

html代码如下:

<div class="container">
    <!-- mian要放开头 -->
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>

  <style>
    .container {
      min-width: 600px;
      overflow: hidden;
      padding: 0 200px;
      box-sizing: border-box;
    }

    .left,
    .main,
    .right {
      float: left;
      min-height: 100px;
    }

    .left {
      position: relative;
      left: -200px;
      margin-left: -100%;
      width: 200px;
      background: green;
    }

    .main {
      width: 100%;
      background: blue;
    }

    .right {
      position: relative;
      right: -200px;
      margin-left: -200px;
      width: 200px;
      background: red;
    }
  </style>

效果如下:

image.png

解析:

  • 这里的.main使用了width:100%,会导致.left.right会换行,所以.leftmargin-left:100%margin-left百分比相对的是父元素),.rightmargin-left: -200px200px刚好是自身的宽度)实现在同一行
  • .containerpadding刚好与.left.right的长度一样,方便.left向左方向,.right向右方向,相对定位移动自身宽度的长度,避免遮挡到.main
  • 然后.container需要设置min-width,因为.leftmargin-left100%,相对的是父元素,如果.container宽度变小,则.main宽度也会变小,如果小于.left的宽度,则不足以和.main在一行,.left则会换行

这里是讲自己的理解,话糙了一点,如果看不懂,自己可以复制代码,自己去看看,会了解的更深。

双飞翼布局

双飞翼布局也是一种三列左右栏固定中间栏边框自适应的网页布局
解决问题也和圣杯布局类似,也是采用三栏全部float浮动左右两栏加上负margin跟中间栏div并排,形成三栏布局。主要不同是在解决 “中间栏div内容不被遮挡”方式不一样

html代码如下(注意⚠:HTML结构发生改变, 多了div.content

  <div class="container">
    <div class="main">
      <div class="content">main</div>
    </div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
  <style>
    .main {
      width: 100%;
      background: blue;
    }

    .content {
      margin: 0 200px;
    }

    .left,
    .main,
    .right {
      float: left;
      min-height: 100px;
    }

    .left {
      margin-left: -100%;
      width: 200px;
      background: green;
    }

    .right {
      margin-left: -200px;
      width: 200px;
      background: red;
    }
  </style>

和圣杯布局主要区别:

  • .main内部多了子元素div.content
  • 子元素div.content里用margin-leftmargin-right,去保证不被.left.right遮挡
  • .left,.right不需要使用定位去避免遮挡.main

Flex布局

  <div class="container">
    <!-- 注意是left main right -->
    <div class="left">left</div>
    <div class="main">main</div>
    <div class="right">right</div>
  </div>
  <style>
    .container {
      display: flex;
      min-height: 100px;
    }

    .left {
      flex-basis: 200px;
      background: green;
    }

    .main {
      flex: auto;
      background: blue;
    }

    .right {
      flex-basis: 200px;
      background: red;
    }
  </style>

解析:

  • flex布局,弹性布局,可以简便、完整、响应式地实现各种页面布局,未来的布局的首选方案(当然如果你要考虑ie,另说)
  • .main使用flex属性,.left.right使用flex-basis 属性
  • flex属性是flex-grow(如果有剩余空间,是否扩大), flex-shrink(如果空间不够,是否压缩) 和 flex-basis(本身的空间大小)的简写,默认值为0 1 auto。后两个属性可选
  • flex属性有两个快捷值:auto (1 1 auto)none (0 0 auto),这里使用的是auto,如果有剩余空间,则扩大,如果空间不够,则压缩

absolute 布局

absolute绝对定位的元素的位置与文档流无关,因此不占据空间。
这一点与相对定位不同,相对定位实际上被看作普通流定位模型的一部分。

  <div class="container">
  <!-- 注意是left main right -->
    <div class="left">left</div>
    <div class="main">main</div>
    <div class="right">right</div>
  </div>
  <style>
    .container {
      position: relative;
    }

    .left,
    .main,
    .right {
      min-height: 100px;
    }

    .left {
      position: absolute;
      left: 0;
      top: 0;
      width: 200px;
      background: green;
    }

    .main {
      margin: 0 200px 0 200px;
      background: blue;
    }

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

解析:

  • .main使用margin避免被.left.right遮挡
  • .left.right使用absolute定位,不占据文档流

总结:

推荐使用:flex布局 > absolute布局 = 双飞翼布局 > 圣杯布局
首选flex布局,因为这是未来的布局方式的首选方案,属性方便设置,实用,好理解;
absolute布局和双飞翼布局适中,圣杯布局不好理解(对我来说);
大家都可以了解下,正所谓技多不压身嘛。