实现常用的两栏布局(左侧固定+右侧自适应)以及三栏布局(圣杯布局和双飞翼布局)

前言

两栏布局和三栏布局是我们常用到的布局形式,下面我们分别进行实现和总结。

一、两栏布局

现在有以下 DOM 结构:

<div class="outer">
  <div class="left">左侧</div>
  <div class="right">右侧</div>
</div>

(1)利用浮动,左边元素宽度固定 ,设置向左浮动。将右边元素的 margin-left 设为固定宽度 。注意,因为右边元素的 width 默认为 auto ,所以会自动撑满父元素。

.outer {
  height: 100px;
}
.left {
  float: left;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  margin-left: 200px;
  height: 100%;
  background: lightseagreen;
}

(2)同样利用浮动,左边元素宽度固定 ,设置向左浮动。右侧元素设置 overflow: hidden; 这样右边就触发了 BFCBFC 的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠。

.outer {
height: 100px;
}
.left {
float: left;
width: 200px;
height: 100%;
background: lightcoral;
}
.right {
overflow: auto;
height: 100%;
background: lightseagreen;
}

(3) 利用 flex 布局,左边元素固定宽度,右边的元素设置 flex: 1

.outer {
  display: flex;
  height: 100px;
}
.left {
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  flex: 1;
  height: 100%;
  background: lightseagreen;
}

(4)利用绝对定位,父级元素设为相对定位。左边元素 absolute 定位,宽度固定。右边元素的 margin-left 的值设为左边元素的宽度值,绝对定位后相当于脱离文档流,right对齐点变为左上角,设置margin即可

.outer {
  position: relative;
  height: 100px;
}
.left {
  position: absolute;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  margin-left: 200px;
  height: 100%;
  background: lightseagreen;
}

(5)利用绝对定位,父级元素设为相对定位。左边元素宽度固定,右边元素 absolute 定位, left 为宽度大小,其余方向定位为 0

.outer {
  position: relative;
  height: 100px;
}
.left {
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  position: absolute;
  left: 200px;
  top: 0;
  right: 0;
  bottom: 0;
  height: 100%;
  background: lightseagreen;
}

二、三栏布局

无论是圣杯布局还是双飞翼布局,都是为了实现一个效果:左右固定宽度,中间部分自适应。两者的区别在于,圣杯布局给中间的 div 设置 padding-left 和 padding-right;而双飞翼布局则在中间的 div 内部创建子 div 放置内容,并在该 div 里用 margin-left 和 margin-right 留出左右宽度。

圣杯布局和双飞翼布局的目的:

  • 三栏布局,中间一栏最先加载和渲染(内容最重要,这就是为什么还需要了解这种布局的原因)。
  • 两侧内容固定,中间内容随着宽度自适应。
  • 一般用于 PC 网页。

圣杯布局和双飞翼布局的技术总结:

  • 使用 float 布局。
  • 两侧使用 margin 负值,以便和中间内容横向重叠。
  • 防止中间内容被两侧覆盖,圣杯布局用 padding ,双飞翼布局用 margin
  • 对margin值的理解:①父子关系时:margin-left是指孩子左边界线与父亲左边界线(若父亲有左padding值,指的就是这条padding线)的距离。margin-right是指孩子右边界线与父亲右边界线(若父亲有右padding值,指的就是这条padding线)的距离。②兄弟关系时:margin-left指的是我的左边界线与我左兄弟的右边界线(若兄弟有右padding值,指的就是这条padding线)之间的距离。margin-right 指的是我的右边界线与我右兄弟的左边界线之间的距离(若兄弟有左padding值,指的就是这条padding线)。
  • 代码中 margin-left: -100% 相对的是父元素的 content 宽度,即不包含 paddigborder 的宽度。因为这里相对于父元素的width,而父元素的width在普通盒子模型中就是content宽度。怪异盒除外
    img

圣杯布局

<body>
    <header>组成头部</header>
    <section class="container">
        <div class="middle">中间部分自适应</div>
        <div class="left">左边栏固定宽度</div>
        <div class="right">右边栏不顾宽度</div>
    </section>
    <footer>组成尾部</footer>
</body>
 body {
     min-width: 700px;
}

header,
footer {
    background: grey;
    border: 1px solid #333;
    text-align: center;
}

.left,
.middle,
.right {
    position: relative;
    float: left;
    min-height: 130px;
}

.container {
    padding: 0 220px 0 200px;
    overflow: hidden;
}

.middle {
    width: 100%;
    background: red;
}

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

.right {
    margin-right: -220px;
    width: 220px;
    background: blue
}

footer {
    clear: both;
}

双飞翼布局

<body>
    <div class="header"></div>
    <div class="container">
      <div class="main"></div>
    </div>
    <div class="left"></div>
    <div class="right"></div>
    <div class="footer"></div>
 </body>
<style>
  * {
    margin: 0;
    padding: 0;
  }
  .header {
    height: 50px;
    background: gray;
  }
  .container {
    background: goldenrod;
    width: 100%;
    height: 100vh;
    float: left;
  }
  .main {
    margin: 0 200px 0 100px;
  }
  .left {
    background: salmon;
    width: 100px;
    height: 100vh;
    float: left;
    margin-left: -100%;
  }
  .right {
    background: skyblue;
    width: 200px;
    height: 100vh;
    float: left;
    margin-left: -200px;
  }
  .footer {
    height: 50px;
    background: gray;
    clear: both;
  }
</style>

通过对圣杯布局和双飞翼布局的介绍可以看出,圣杯布局在DOM结构上显得更加直观和自然,且在日常开发过程中,更容易形成这样的DOM结构(通常<aside><article>/<section>一起被嵌套在<main>中);而双飞翼布局在实现上由于不需要使用定位,所以更加简洁,且允许的页面最小宽度通常比圣杯布局更小。

其实通过思考不难发现,两者在代码实现上都额外引入了一个<div>标签,其目的都是为了既能保证中间栏产生浮动(浮动后还必须显式设置宽度),又能限制自身宽度为两侧栏留出空间。

从这个角度出发,如果去掉额外添加的<div>标签,能否完成相同的布局呢?答案是肯定的,不过这需要在兼容性上做出牺牲

<div id="header"></div>
<div id="center" class="column"></div>
<div id="left" class="column"></div>
<div id="right" class="column"></div>
<div id="footer"></div>

1. 通过calc()可以十分方便地计算出center应该占据的自适应宽度,目前calc()支持到IE9。
.column {
  float: left;
}
    
#center {
  margin-left: 200px;
  margin-right: 150px;
  width: calc(100% - 350px);
}

2. 使用border-box 使用border-box可以将center的整个盒模型宽度设置为父元素的100%宽度,此时再利用padding-left和padding-right可以自动得到中间栏的自适应宽度。不过需要注意的是,由于padding是盒子的一部分,所以padding部分会具有中间栏的背景色 目前box-sizing支持到IE8。

.column {
  float: left;
}
    
#center {
  padding-left: 200px;
  padding-right: 150px;
  box-sizing: border-box;
  width: 100%;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值