流体布局,圣杯布局,双飞翼布局 具体怎么实现呢?

129 阅读2分钟

流体布局

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .left { 
      float: left; 
      width: 100px; 
      height: 200px; 
      background: red; 
    }
    .right { 
      float: right; 
      width: 200px; 
      height: 200px; 
      background: lightblue; 
    }
    .main { 
      margin-left: 120px; 
      margin-right: 220px; 
      height: 200px; 
      background: green; 
    }
  </style>
</head>
<body>
  <div class="content">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
</body>
</html>

image.png 流体布局比较简单。

圣杯布局和双飞翼布局都是为了实现左右两栏固定宽度,中间部分自适应的三栏布局,不过两者实现的原理有所不同,以下是实现思路:

圣杯布局

  1. 最外边的content盒子是父容器,main设置左右内填充,main,left和right都浮动;

image.png 设置content的最小宽度为200px,避免浏览器窗口变化时,布局混乱

设置overflow: hidden变为BFC,清除浮动带来的影响

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .content{
      border: 1px solid #000;
      padding-left: 100px;
      padding-right: 100px;
      min-width: 200px;
      overflow: hidden;
    }
    .main, .left, .right{
      float: left;
    }
    .main{
      background-color: pink;
      height: 300px;
      width: 100%;
    }
    .left{
      background-color: orange;
      width: 100px;
      height: 300px;
    }
    .right{
      background-color: lightblue;
      width: 100px;
      height: 300px;
    }
  </style>
</head>
<body>
  <div class="content">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
</body>
</html>
  1. 中间main宽度占满,width:100%,left在浮动下通过设置margin-left: -100%实现到上一行紧挨着main的padding-left的右边;

或者这样理解:考虑浮动的特性,假设main是固定宽度的,全都左浮动以后,main、left、right应该排在同一行。要让left移动到左边,只需要向左边移动一个main的宽度就可以了,所以就是margin-left:-100%;

为什么使用margin-left:-100%就能实现呢?

这里margin-left改变的是水平方向上的偏移量,并不是你直观看到的高度。

标准文档流中的.left元素其实是跟随在.center元素的右边界之后。但因为父元素设置了左右padding的缘故,才被挤到了第二行(所以表面上看起来是高度改变了)。

margin-left的作用原本是迫使元素向右移动,通过给margin-left设置负值,可以同时起到破坏文档流强制左移的作用,.left强制左移100%,便会达到顶部最左侧位置。

image.png

  1. left盒子需要移到main盒子左边,也就是填充padding-left的位置,position: relative;left: -100px;

image.png

  1. left盒子布局完成,接下来是right盒子,margin-left: -100px;position: relative;right: -100px;

image.png 到此,圣杯布局完成,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .content{
      border: 1px solid #000;
      padding-left: 100px;
      padding-right: 100px;
      min-width: 200px;
      overflow: hidden;
    }
    .main, .left, .right{
      float: left;
    }
    .main{
      background-color: pink;
      height: 300px;
      width: 100%;
    }
    .left{
      background-color: orange;
      width: 100px;
      height: 300px;
      margin-left: -100%;
      position: relative;
      left: -100px;
    }
    .right{
      background-color: lightblue;
      width: 100px;
      height: 300px;
      margin-left: -100px;
      position: relative;
      right: -100px;
    }
  </style>
</head>
<body>
  <div class="content">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
</body>
</html>

双飞翼布局

  1. 与圣杯布局不同的是content不设置内填充,main,left,right都浮动

image.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>双飞翼</title>
    <style>
        .left {
            width: 200px;
            height: 300px;
            background: orange;
            float: left;
        }
        .right {
            width: 200px;
            height: 300px;
            background: lightblue;
            float: right;
        }
        .main {
            width: 100%;
            float: left;
        }
        .wrap {
            height: 300px;
            background: pink;
            margin: 0 200px;
        }
    </style>
</head>
<body>
<div class="content">
    <div class="main">
        <div class="wrap">main</div>
    </div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>
</body>
</html>
  1. 然后只需要在left加margin-left: -100%;right加margin-left: -200px;即可完成布局

image.png 完整代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>双飞翼</title>
    <style>
        .left {
            width: 200px;
            height: 300px;
            background: orange;
            float: left;
            margin-left: -100%;
        }
        .right {
            width: 200px;
            height: 300px;
            background: lightblue;
            float: right;
            margin-left: -200px;
        }
        .main {
            width: 100%;
            float: left;
        }
        .wrap {
            height: 300px;
            background: pink;
            margin: 0 200px;
        }
    </style>
</head>
<body>
<div class="content">
    <div class="main">
        <div class="wrap">main</div>
    </div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>
</body>
</html>

圣杯布局和双飞翼布局本质区别

image.png 圣杯布局:float + position

双飞翼布局:float

总结

圣杯布局是给三列的父元素(content),加上 左margin 和 右margin(或者 padding),将三列挤到中间来,这样左边和右边就会预留出位置。

双飞翼布局是在main的div里又插入一个div,通过调整内部div的margin值,实现中间栏自适应,内容写到内部div中。

image.png