# 多列布局

# 左列定宽,右列自适应

该布局方式非常常见,适用于定宽的一侧常为导航,自适应的一侧为内容的布局

# 1. 利用 float+margin 实现

.left {
  float: left;
  width: 100px;
}
.right {
  margin-left: 100px;
}

注:IE6 会有 3px 的 bug

# 2. 利用 float+margin(fix)实现

clipboard.png

<div class="parent">
  <div class="left"></div>
  <div class="right-fix">
    <div class="right"></div>
  </div>
</div>
.left {
  width: 100px;
  float: left;
}
.right-fix {
  width: 100%;
  margin-left: -100px;
  float: right;
}
.right {
  margin-left: 100px;
}

# 3. 使用 float+overflow 实现

.left {
  width: 100px;
  float: left;
}
.right {
  overflow: hidden;
}

overflow:hidden,触发 bfc 模式,浮动无法影响,隔离其他元素,IE6 不支持,左侧 left 设置 margin-left 当作 left 与 right 之间的边距,右侧利用 overflow:hidden 进行形成 bfc 模式 如果我们需要将两列设置为等高,可以用下述方法将“背景”设置为等高,其实并不是内容的等高

.left {
  width: 100px;
  float: left;
}
.right {
  overflow: hidden;
}
.parent {
  overflow: hidden;
}
.left,
.right {
  padding-bottom: 9999px;
  margin-bottom: -9999px;
}

# 4. 使用 table 实现

.parent {
  display: table;
  table-layout: fixed;
  width: 100%;
}
.left {
  width: 100px;
}
.right,
.left {
  display: table-cell;
}

# 5. 实用 flex 实现

.parent {
  display: flex;
}
.left {
  width: 100px;
}
.right {
  flex: 1;
}

利用右侧容器的 flex:1,均分了剩余的宽度,也实现了同样的效果。而 align-items 默认值为 stretch,故二者高度相等

# 右列定宽,左列自适应

# 1. 实用 float+margin 实现

.parent {
  background: red;
  height: 100px;
  margin: 0 auto;
}
.left {
  background: green;
  margin-right: -100px;
  width: 100%;
  float: left;
}
.right {
  float: right;
  width: 100px;
  background: blue;
}

# 2. 使用 table 实现

.parent {
  display: table;
  table-layout: fixed;
  width: 100%;
}
.left {
  display: table-cell;
}
.right {
  width: 100px;
  display: table-cell;
}

# 3. 实用 flex 实现

.parent {
  display: flex;
}
.left {
  flex: 1;
}
.right {
  width: 100px;
}

# 两列定宽,一列自适应

clipboard.png

基本 html 结构为父容器为 parent,自容器为 left,center,right.其中,left,center 定宽,right 自适应

# 1. 利用 float+margin 实现

.left,.center{float:left:width:200px;}
.right{margin-left:400px;}

# 2. 利用 float+overflow 实现

.left,.center{float:left:width:200px;}
.right{overflow:hidden;}

# 3. 利用 table 实现

.parent {
  display: table;
  table-layout: fixed;
  width: 100%;
}
.left,
.center,
.right {
  display: table-cell;
}
.left,
.center {
  width: 200px;
}

# 4. 利用 flex 实现

.parent {
  display: flex;
}
.left,
.center {
  width: 100px;
}
.right {
  flex: 1;
}

# 两侧定宽,中栏自适应

clipboard.png

# 1. 利用 float+margin 实现

.left{width:100px;float:left;}
.center{float:left;width:100%;margin-right:-200px;}
.right{width:100px;float:right;}

# 2. 利用 table 实现

.parent {
  width: 100%;
  display: table;
  table-layout: fixed;
}
.left,
.center,
.right {
  display: table-cell;
}
.left {
  width: 100px;
}
.right {
  width: 100px;
}

# 3. 利用 flex 实现

.parent {
  display: flex;
}
.left {
  width: 100px;
}
.center {
  flex: 1;
}
.right {
  width: 100px;
}

# 一列不定宽,一列自适应

clipboard.png

# 1. 利用 float+overflow 实现

.left {
  float: left;
}
.right {
  overflow: hidden;
}

# 2. 利用 table 实现

.parent {
  display: table;
  table-layout: fixed;
  width: 100%;
}
.left {
  width: 0.1%;
}
.left,
.right {
  display: table-cell;
}

# 3. 利用 flex 实现

.parent {
  display: flex;
}
.right {
  flex: 1;
}

# 多列等分布局

多列等分布局常出现在内容中,多数为功能的,同阶级内容的并排显示等。

clipboard.png

html 结构如下所示

<div class="parent">
  <div class="column">1</div>
  <div class="column">1</div>
  <div class="column">1</div>
  <div class="column">1</div>
</div>

# 1. 实用 float 实现

.parent {
  margin-left: -20px;
} /*假设列之间的间距为20px*/
.column {
  float: left;
  width: 25%;
  padding-left: 20px;
  box-sizing: border-box;
}

# 2. 利用 table 实现

.parent-fix {
  margin-left: -20px;
}
.parent {
  display: table;
  table-layout: fixed;
  width: 100%;
}
.column {
  display: table-cell;
  padding-left: 20px;
}

# 3. 利用 flex 实现

.parent {
  display: flex;
}
.column {
  flex: 1;
}
.column + .column {
  margin-left: 20px;
}

# 九宫格布局

# 1. 使用 table 实现

<div class="parent">
  <div class="row">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
  <div class="row">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
  <div class="row">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
</div>
.parent {
  display: table;
  table-layout: fixed;
  width: 100%;
}
.row {
  display: table-row;
}
.item {
  display: table-cell;
  width: 33.3%;
  height: 200px;
}

# 2. 实用 flex 实现

<div class="parent">
  <div class="row">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
  <div class="row">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
  <div class="row">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
</div>
.parent {
  display: flex;
  flex-direction: column;
}
.row {
  height: 100px;
  display: flex;
}
.item {
  width: 100px;
  background: red;
}

# 全屏布局

clipboard.png

# 1. 利用绝对定位实现

<div class="parent">
  <div class="top">top</div>
  <div class="left">left</div>
  <div class="right">right</div>
  <div class="bottom">bottom</div>
</div>

html,body,parent{height:100%;overflow:hidden;}
.top{position:absolute:top:0;left:0;right:0;height:100px;}
.left{position:absolute;top:100px;left:0;bottom:50px;width:200px;}
.right{position:absolute;overflow:auto;left:200px;right:0;top:100px;bottom:50px;}
.bottom{position:absolute;left:0;right:0;bottom:0;height:50px;}

# 2. 利用 flex 实现

<div class="parent">
  <div class="top">top</div>
  <div class="middle">
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
  <div class="bottom">bottom</div>
</div>
.parent {
  display: flex;
  flex-direction: column;
}
.top {
  height: 100px;
}
.bottom {
  height: 50px;
}
.middle {
  flex: 1;
  display: flex;
}
.left {
  width: 200px;
}
.right {
  flex: 1;
  overflow: auto;
}

# 三栏-表格布局

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>表格布局</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      .wrapper {
        display: table;
        width: 100%;
      }
      .left,
      .right,
      .center {
        min-height: 100px;
        display: table-cell;
      }
      .left {
        width: 300px;
        background-color: red;
      }
      .center {
        background-color: orange;
      }
      .right {
        background-color: blue;
        width: 300px;
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <aside class="left"></aside>
      <main class="center">
        <h1>表格布局</h1>
        <p>父元素display: table;并且宽度为100%</p>
        <p>每一个子元素display: table-cell;</p>
        <p>左右两侧添加宽度,中间不加宽度</p>
      </main>
      <aside class="right"></aside>
    </div>
  </body>
</html>

# 三栏-浮动方案

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      .left,
      .right,
      .center {
        min-height: 100px;
      }
      .left {
        background-color: red;
        width: 200px;
        float: left;
      }
      .right {
        background-color: blue;
        width: 200px;
        float: right;
      }
      .center {
        background-color: orange;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <aside class="left"></aside>
    <aside class="right"></aside>
    <main class="center">
      <h1>浮动解决方案</h1>
      <p>方法:left和right写在center前面,并且分别左右浮动;</p>
      <p>
        中间的这个div因为是块级元素,所以在水平方向上按照他的包容块自动撑开。
      </p>
      <p>简单,但是中心部分过长下面会溢出,然后文字就会跑到两边去。</p>
    </main>
  </body>
</html>

# 三栏-绝对定位

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>绝对定位三栏布局</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      aside {
        position: absolute;
        width: 300px;
        min-height: 100px;
      }

      aside.left {
        left: 0;
        background-color: red;
      }

      aside.right {
        right: 0;
        background-color: blue;
      }

      main.center {
        position: absolute;
        left: 300px;
        right: 300px;
        background-color: orange;
      }
    </style>
  </head>

  <body>
    <aside class="left"></aside>
    <aside class="right"></aside>
    <main class="center">
      <h1>绝对定位解决方案</h1>
      <p>左右区域分别postion:absolute,固定到左右两边</p>
      <p>中间区域postion:absolute;left:300px; right: 300px</p>
      <p>给总的宽度加一个min-width,不然缩小窗口会有毛病</p>
    </main>
  </body>
</html>

# 三栏-网格布局

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>网格布局</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      /* 网格布局 */
      .wrapper {
        display: grid;
        width: 100%;
        grid-template-columns: 300px 1fr 300px;
      }

      .left {
        background-color: red;
      }
      .center {
        background-color: orange;
      }
      .right {
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <aside class="left"></aside>
      <main class="center">
        <h1>表格布局</h1>
        <p>父元素display: table;并且宽度为100%</p>
        <p>每一个子元素display: table-cell;</p>
        <p>左右两侧添加宽度,中间不加宽度</p>
      </main>
      <aside class="right"></aside>
    </div>
  </body>
</html>

# 三栏-flex

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

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

      .wrapper {
        display: flex;
      }

      .left {
        background-color: red;
        width: 300px;
      }

      .center {
        background-color: orange;
        flex: 1;
      }

      .right {
        background-color: blue;
        width: 300px;
      }
    </style>
  </head>

  <body>
    <div class="wrapper">
      <aside class="left"></aside>
      <main class="center">
        <h1>flex布局解决方案</h1>
        <p>包裹这个3个块的父元素display: flex; 中间的元素flex: 1;</p>
      </main>
      <aside class="right"></aside>
    </div>
  </body>
</html>

# 左边定宽,右边自适应方案

/* 方案1 float + margin */
.left {
  width: 120px;
  float: left;
}
.right {
  margin-left: 120px;
}
/* 方案2 float + calc */
.left {
  width: 120px;
  float: left;
}
.right {
  width: calc(100% - 120px);
  float: left;
}

# 左右两边定宽,中间自适应

.wrap {
  width: 100%;
  height: 200px;
}
.wrap > div {
  height: 100%;
}
/* 方案1 float,float + calc */
.left {
  width: 120px;
  float: left;
}
.right {
  width: 120px;
  float: right;
}
.center {
  /* 不设定 width */
  margin: 0 120px;
}
/* 方案2 圣杯布局(设置 BFC,margin 负值法) */
.left {
  width: 120px;
  float: left;
}
.right {
  width: 120px;
  float: right;
}
.center {
  width: calc(100% - 240px);
  margin-left: 120px;
}
/* 方案3 flex */
.wrap {
  display: flex;
}
.left {
  width: 120px;
}
.right {
  width: 120px;
}
.center {
  /* 自己撑开 */
  flex: 1;
}

# 如何实现一个三列布局,中间固定,两边自适应?

<header>
  <style>
    .contaniner {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
    }

    .item {
      border: 1px solid red;
      height: 100%;
    }

    .center {
      width: 100px;
    }

    .left,
    .right {
      width: calc(50% - 50px);
    }
  </style>
</header>
<div class="contaniner">
  <div class="item left">
    left
  </div>
  <div class="item center">
    中间
  </div>
  <div class="item right">
    右边
  </div>
</div>

相对应的问题来了,如何实现一个三栏布局,中间自适应,两边固定?

只需要把中间和两边的宽度调整一下即可。

   .center {
     width: calc(100% - 200px);

}

   .left,
   .right {
     width: 100px;
   }

同样可以完成中间自适应,两边固定的布局:

<body class="container">
  <div class="item left">100px宽</div>
  <div class="item center">自适应</div>
  <div class="item right">100px宽</div>
</body>

<style>
  .container {
    border: 1px solid black;
    width: 100vw;
    height: 100vh;

    display: flex;
    flex-direction: row;
    justify-content: space-between;
  }

  .item {
    border: 1px solid red;
    height: 100%;
  }

  .center {
    flex: 1;
  }

  .left,
  .right {
    width: 100px;
  }
</style>

在上一段代码的基础上更改一下即可完成中间固定,两边自适应

.center {
  width: 100px;
}

.left,
.right {
  flex: 1;
}

# css 实现三栏布局,中间自适应

方法一:自身浮动法。左栏左浮动,右栏右浮动。

.left,
.right {
  height: 300px;

  width: 200px;
}

.right {
  float: right;
  background-color: red;
}

.left {
  float: left;
  background-color: #080808;
}

.middle {
  height: 300px;

  margin: 0 200px; //没有这行,当宽度缩小到一定程度的时候,中间的内容可能换行

  background-color: blue;
}
body {
  margin: 0;

  padding: 0;
}

.left,
.right {
  height: 300px;

  width: 200px;

  float: left;
}

.right {
  margin-left: -200px;

  background-color: red;
}

.left {
  margin-left: -100%;

  background-color: #080808;
}

.middle {
  height: 300px;
  width: 100%;
  float: left;
  background-color: blue;
}
<div class="middle">middle</div>

<div class="left">left</div>

<div class="right">right</div>
body {
  margin: 0;

  padding: 0;
}

.left,
.right {
  top: 0;

  height: 300px;

  width: 200px;

  position: absolute;
}

.right {
  right: 0;

  background-color: red;
}

.left {
  left: 0;

  background-color: #080808;
}

.middle {
  margin: 0 200px;

  height: 300px;

  background-color: blue;
}

这种方法没有严格限定中间这栏放置何处

<div class="left">left</div>
<div class="middle">middle</div>
<div class="right">right</div>

# 三栏布局

假设高度已知,请写出三栏布局,其中左右栏宽 300px,中间自适应

# 几种常见的 CSS 布局

流体布局

.left {
  float: left;
  width: 100px;
  height: 200px;
  background: red;
}
.right {
  float: right;
  width: 200px;
  height: 200px;
  background: blue;
}
.main {
  margin-left: 120px;
  margin-right: 220px;
  height: 200px;
  background: green;
}
<div class="container">
  <div class="left"></div>
  <div class="right"></div>
  <div class="main"></div>
</div>

圣杯布局

.container {
  margin-left: 120px;
  margin-right: 220px;
}
.main {
  float: left;
  width: 100%;
  height: 300px;
  background: green;
}
.left {
  position: relative;
  left: -120px;
  float: left;
  height: 300px;
  width: 100px;
  margin-left: -100%;
  background: red;
}
.right {
  position: relative;
  right: -220px;
  float: right;
  height: 300px;
  width: 200px;
  margin-left: -200px;
  background: blue;
}
<div class="container">
  <div class="main"></div>
  <div class="left"></div>
  <div class="right"></div>
</div>

双飞翼布局

.content {
  float: left;
  width: 100%;
}
.main {
  height: 200px;
  margin-left: 110px;
  margin-right: 220px;
  background: green;
}
.main::after {
  content: '';
  display: block;
  font-size: 0;
  height: 0;
  zoom: 1;
  clear: both;
}
.left {
  float: left;
  height: 200px;
  width: 100px;
  margin-left: -100%;
  background: red;
}
.right {
  float: right;
  height: 200px;
  width: 200px;
  margin-left: -200px;
  background: blue;
}
<div class="content">
  <div class="main"></div>
</div>
<div class="left"></div>
<div class="right"></div>

# 右边宽度固定,左边自适应

body {
  display: flex;
}
.left {
  background-color: rebeccapurple;
  height: 200px;
  flex: 1;
}
.right {
  background-color: red;
  height: 200px;
  width: 100px;
}
<body>
  <div class="left"></div>
  <div class="right"></div>
</body>
div {
  height: 200px;
}
.left {
  float: right;
  width: 200px;
  background-color: rebeccapurple;
}
.right {
  margin-right: 200px;
  background-color: red;
}
<body>
  <div class="left"></div>
  <div class="right"></div>
</body>

# 三栏式布局

方案一:position(绝对定位法) center 的 div 需要放在最后面 绝对定位法原理将左右两边使用 absolute 定位,因为绝对定位使其脱离文档流,后面的 center 会自然流动到他们的上卖弄,然后 margin 属性,留出左右两边的宽度。就可以自适应了。 方案二:float 自身浮动法 center 的 div 需要放到后面 自身浮动法的原理就是对左右使用 float:left 和 float:right,float 使左右两个元素脱离文档流,中间的正常文档流中,使用 margin 指定左右外边距对其进行一个定位。 方案三(圣杯布局):原理就是 margin 负值法。使用圣杯布局首先需要在 center 元素外部包含一个 div,包含的 div 需要设置 float 属性使其形成一个 BFC,并且这个宽度和 margin 的负值进行匹配

# css 多列等高如何实现?

  • 利用 padding-bottom|margin-bottom 正负值相抵;
  • 设置父容器设置超出隐藏(overflow:hidden),这样子父容器的高度就还是它里面的列没有设定 padding-bottom 时的高度
  • 当它里面的任 一列高度增加了,则父容器的高度被撑到里面最高那列的高度
  • 其他比这列矮的列会用它们的 padding-bottom 补偿这部分高度差

# 如何实现两列布局

  1. 将元素的 display 设置为行内元素
  2. 两个元素全部使用浮动
  3. 一个元素左浮动,第二个元素不便,同时设置一个 margin-left 值
  4. 使用 flex-box 布局

# 做一个两栏布局,左边 fixed width,右边 responsive

# Css 实现三列布局 Css 实现保持长宽比 1:1 Css 实现两个自适应等宽元素中间空 10 个像素。

# 左右布局:左边定宽、右边自适应,不少于 3 种方法