[css] 圣杯布局 双飞翼布局

36 篇文章 1 订阅

三栏式布局

三栏布局,两边的盒子宽度固定,中间盒子自适应,“圣杯”和“双飞翼就是三栏式布局,它们实现的效果是一样的,差别在于其实现的思想。
在这里插入图片描述

圣杯布局

方法1:使用float布局框架 , 用margin为负值 , position: relative定位

圣杯:父盒子包含三个子盒子(左,中,右)

  • 中间盒子的宽度设置为 width: 100%; 独占一行;
  • 使用负边距(均是 margin-left)把左右两边的盒子都拉上去和中间盒子同一行;
    • .left {margin-left:-100%;} 把左边的盒子拉上去
    • .right {margin-left:-右边盒子宽度px;} 把右边的盒子拉上去
  • 父盒子设置左右的 padding 来为左右盒子留位置;
  • 对左右盒子使用相对布局来占据 padding 的空白,避免中间盒子的内容被左右盒子覆盖;

一起来看看淘宝的头部实现:
在这里插入图片描述通过缩放页面就可以发现,随着页面的宽度的变化,这三栏布局是中间盒子优先渲染,两边的盒子框子固定不变,即使页面宽度变小,也不影响我们的浏览

在这里插入图片描述

分析:

基础布局

    <div class="header">头部</div>
    <div class="container">
        <div class="center"></div>
        <div class="left"></div>
        <div class="right"></div>
    </div>
    <div class="footer">底部</div>
        .header{
            width: 100%;
            height: 100px;
            background-color: rgb(228, 127, 127);
        }
        .footer{
            width: 100%;
            height: 100px;
            background-color: rgb(189, 85, 85);
        }
        .container{
            width: 100%;
        }
        .center{
            width:100%;
            height: 100px;
            background-color: rgb(129, 113, 221);
        }
        .left{
            width: 200px;
            height: 100px;
            background-color: rgb(175, 226, 133);
        }
        .right{
            width: 100px;
            height: 100px;
            background-color: rgb(133, 226, 221);
        }

在这里插入图片描述
浮动
在这里插入图片描述

在这里插入图片描述
出现了高度塌陷,底部footer补位上来了
给footer清除浮动带来的影响
[css] 解决问题—高度塌陷
在这里插入图片描述

在这里插入图片描述
大家可以看到,三栏并没有在父元素的一行显示,就是因为中间盒子我们给了百分之百的宽度。所有左右两个盒子才会被挤下来。
那么如何让它们呈现出一行三列的效果呢?那就要让左边的盒子要到中间盒子的最左边,右边的盒子到中间盒子的最右边。换个想法,如果中间盒子不是100%的宽度,那么按照文档流,左边的盒子一定会在中间盒子的后面显示,接着显示右边的盒子。但是现在中间盒子是满屏了的,所以左右两个盒子被挤到下一行显示。我们要做到的是让左右两个盒子都上去。此时,CSS的负边距(negative margin)该上阵了。

在这里插入图片描述
在这里插入图片描述

也可以这样理解:margin负值会改变元素占据的空间,你要是不给他负值,一定是在第二行显示,因为他占据空间,第一行没有地方放他,你要是给一个-100px,和他宽度一样,那他占据的空间就是0,自然就回跑到上面去,

利用margin-left的负值将左侧栏挪上来

左侧栏margin-left赋值为-100%在这里插入图片描述
在这里插入图片描述
左侧上去后,右侧就往前走一走

让右侧上来,
在这里插入图片描述
在这里插入图片描述

利用margin-left的负值将右侧栏挪上来
右侧栏margin-left赋值为负的自身宽度。在这里插入图片描述

在这里插入图片描述
注意:这里的左右侧栏都是附在内容栏上的,内容栏被压在下面。(把中间部分height扩大,这样看的清晰)
在这里插入图片描述
在这里插入图片描述

将内容栏被左右压在底下的部分,通过container添加padding属性透出来。
在这里插入图片描述

在这里插入图片描述

左右侧边栏利用position: relative,移出内容区域
在这里插入图片描述

在这里插入图片描述
把中间的紫色高度恢复为100px
在这里插入图片描述

代码:
  • 先写center部分,width 100%
  • center,left,right都是左浮动
  • 设置margin-left为负值让left和right部分回到与center部分同一行
  • 父容器container设置padding-left和padding-right
  • 设置相对定位,让left和right部分移动到两边
<!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>
        .header{
            width: 100%;
            height: 100px;
            background-color: rgb(228, 127, 127);
        }
        .footer{
            width: 100%;
            height: 100px;
            background-color: rgb(189, 85, 85);
            clear: both;
        }
        .container{
            width: 100%;
            padding: 0 100px 0 200px;
            box-sizing: border-box;
        }
        .center{
            width:100%;
            height:100px;
            background-color: rgb(129, 113, 221);
            float: left;
        }
        .left{
            width: 200px;
            height: 100px;
            background-color: rgb(175, 226, 133);
            float: left;
            margin-left: -100%;
            position: relative;
            left: -200px;
        }
        .right{
            width: 100px;
            height: 100px;
            background-color: rgb(133, 226, 221);
            float: left;
            margin-left: -100px;
            position: relative;
            left: 100px;
        }
    </style>
</head>

<body>
    <div class="header">头部</div>
    <div class="container">
        <div class="center"></div>
        <div class="left"></div>
        <div class="right"></div>
    </div>
    <div class="footer">底部</div>

</body>

</html>
缺点

center部分的最小宽度不能小于left部分的宽度
其中一列内容高度拉长,其他两列的高度不会自动填充

方法2:calc

兼容到IE9
在这里插入图片描述
在这里插入图片描述

        html,body {
            height: 100%;
            overflow: hidden;
        }

        .container {
            height: 100%;
        }

        .left,.right {
            width: 200px;
            min-height: 200px;
            background: lightblue;
            float: left;
        }

        .center {
            width: calc(100% - 400px);
            min-height: 200px;
            background: lightsalmon;
            float: left;
        }
方法3: flex布局
     html,body {
         height: 100%;
         overflow: hidden;
     }
        
	.container{
      display: flex;
      /*space-between:空白均匀分布到元素间*/
      justify-content: space-between;
      height: 100%;
    }

    .left,.right{
      /*flex:放大倍数 缩小倍数 占据大小*/
      flex: 0 0 200px;
      height: 200px;
      background: lightblue;
    }

    .center{
      /*flex:1 把剩余空间全都占据(自动分配占据空间)*/
      flex: 1;
      min-height: 200px;
      background: lightsalmon;
    }

  <div class="container">
    <div class="left"></div>
    <div class="center"></div>
    <div class="right"></div>
  </div>

在这里插入图片描述

方法4 定位方式布局
     html, body {
        height: 100%;
        overflow: hidden;
    }
    .container{
      position: relative;
      height: 100%;
    }

    .left,.right{
      position: absolute;
      top: 0;
      width: 200px;
      min-height: 200px;
      background: lightblue;
    }

    .left{
      left: 0;
    }

    .right{
      right: 0;
    }

    .center{
      margin: 0 200px;
      min-height: 200px;
      background: lightsalmon;
    }

  <div class="container">
    <div class="left"></div>
    <div class="center"></div>
    <div class="right"></div>
  </div>

双飞翼布局

双飞翼:父盒子包含三个子盒子(左,中,右),中间的子盒子里再加一个子盒子。

  • 中间盒子的宽度设置为 width: 100%; 独占一行;
  • 使用负边距(均是 margin-left)把左右两边的盒子都拉上去和中间盒子同一行;
  • 在中间盒子里面再添加一个 div,然后对这个 div 设置 margin-left 和 margin-right来为左右盒子留位置;
分析:
    <div class="header">头部</div>
    <div class="container">
        <!-- 中间的 div 必须写在最前面 -->
        <div class="main">
            <div class="center">中间弹性区</div>
        </div>
        <div class="left">左边栏</div>
        <div class="right">右边栏</div>
    </div>
    <div class="footer">底部</div>

从上面的DOM结构来看,双飞翼布局与圣杯布局最大的不同点便是在此,双飞翼布局中,将中间栏放在一个div内部包裹起来了,多了一层DOM结构

在这里插入图片描述

基础布局

在这里插入图片描述

在这里插入图片描述

为左右两列预留出空间,设置center的左右margin。
在这里插入图片描述

在这里插入图片描述
将左边栏放置到预留位置:
在这里插入图片描述

在这里插入图片描述

将右边栏放置到预留位置:
在这里插入图片描述
在这里插入图片描述

代码
  • 先写center部分,width 100%
  • center,left,right都是左浮动
  • 在中间盒子里再增加一个子盒子,设置子盒子的 margin-left, margin-right来让出空位,
  • 设置margin-left为负值让left和right部分回到与center部分同一行
<!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>
        .header {
            width: 100%;
            height: 100px;
            background-color: rgb(228, 127, 127);
        }
        .footer {
            width: 100%;
            height: 100px;
            background-color: rgb(189, 85, 85);
            clear: both;
        }
        .container {
            width: 100%;
            height: 100px;
        }
        .main {
            width: 100%;
            height: 100px;
            background-color: rgb(129, 113, 221);
            float: left;
        }
        .main .center{
            height: 100px;
            background-color: rgb(233, 162, 215);
            margin-left: 200px;
            margin-right: 100px;
        }
        .left {
            width: 200px;
            height: 100px;
            background-color: rgb(175, 226, 133);
            float: left;
            margin-left: -100%;
        }
        .right {
            width: 100px;
            height: 100px;
            background-color: rgb(133, 226, 221);
            float: left;
            margin-left: -100px;
        }
    </style>
</head>

<body>
    <div class="header">头部</div>
    <div class="container">
        <!-- 中间的 div 必须写在最前面 -->
        <div class="main">
            <div class="center">中间弹性区</div>
        </div>
        <div class="left">左边栏</div>
        <div class="right">右边栏</div>
    </div>
    <div class="footer">底部</div>

</body>

</html>

圣杯和双飞翼异同

圣杯布局和双飞翼布局解决的问题是一样的,都是两边定宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。

  • 两种方法基本思路都相同:首先让中间盒子 100% 宽度占满同一高度的空间,在左右两个盒子被挤出中间盒子所在区域时,使用 margin-left 的负值将左右两个盒子拉回与中间盒子同一高度的空间。接下来进行一些调整避免中间盒子的内容被左右盒子遮挡。
  • 主要区别在于 如何使中间盒子的内容不被左右盒子遮挡
    • 圣杯布局的方法:设置父盒子的 padding 值为左右盒子留出空位,再利用相对定位对左右盒子调整位置占据 padding 出来的空位;
    • 双飞翼布局的方法:在中间盒子里再增加一个子盒子,直接设置这个子盒子的 margin 值来让出空位,而不用再调整左右盒子。

简单说起来就是双飞翼布局比圣杯布局多创建了一个 div,但不用相对布局了,少设置几个属性。

这样说也行
说说圣杯布局与双飞翼布局的区别吧:

相同点:

1.两个都是三栏式布局,中间栏优先放,保证优先渲染

2.实现方式都是左浮动

不同点:

1圣杯布局是中间栏为两边腾开位置。双飞翼布局则是中间栏不变,将内容部分为两边腾开位置






参考:
CSS 布局经典问题初步整理

圣杯布局和双飞翼布局

圣杯布局和双飞翼布局的理解与思考
双飞翼布局

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值