yangbo5207 / everyday

Something I learn every day.
5 stars 0 forks source link

CSS: 两/三列布局的实现 #46

Open yangbo5207 opened 8 years ago

yangbo5207 commented 8 years ago

CSS: 两列/三列布局详解

所谓的两列/三列布局,一般来说,指的是左右两边的列固定宽度,中间列宽度自适应。实现方式也有很多种,在实际应用中也经常会遇到这类型的需求,因此这里将自己所遇到的方法总结一下。

1. 使用BFC的原理实现

BFC的规则之一,就是BFC区域,不会与float box重叠,因此我们可以利用这一点来实现3列布局。

html代码如下

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

css代码如下

.left {
  float: left;
  margin-right: 10px;
  width: 100px;
  height: 100px;
  background-color: orange;
}
.right {
  float: right;
  margin-left: 10px;
  width: 100px;
  height: 100px;
  background-color: orange;
}
.main {
  height: 100px;
  background-color: green;
  overflow: hidden;
}

实例地址: http://codepen.io/anon/pen/jWJpEo 兼容性: IE6+ 都没有问题 缺点:主要内容模块无法最先加载,当页面中内容较多时会影响用户体验。因此为了解决这个问题,有了如下的布局方案双飞翼布局

在IE6,IE7中使用overflow:hidden会没有效果,子元素超出父元素部分任然不会隐藏,解决办法就是在该元素的父级添加如下属性即可position: relative。这个问题并不影响本例中的布局实现。

2.双飞翼布局

这种布局方案最早由淘宝提出,主要为了主列能够被最先加载。 实现原理:

  1. 让主列外面添加一个wrap,主列wrap,以及2子列都左浮动。
  2. 设置主列wrap宽度为100%,将子列的margin-left设置为负值,让子列能够排列在左右两侧。
  3. 这是主列的margin-leftmargin-right比左右两列的宽度大一点,则可以设置出来主列与子列之间的间隙。 html代码如下
<div class="wrap">
  <div class="main-content">
    <div class="main"></div>
  </div>
  <div class="left"></div>
  <div class="right"></div>
</div>

css代码如下

.wrap {
  width: 100%;
}
.wrap::after {
  display: block;
  content: '';
  font-size: 0;
  height: 0;
  clear: both;
  zoom: 1;
}
.main-content {
  float: left;
  width: 100%;
}
.main {
  height: 100px;
  background-color: green;
  margin-left: 110px;
  margin-right: 110px;
}

.left {
  float: left;
  width: 100px;
  height: 100px;
  background-color: orange;
  margin-left: -100%;
}
.right {
  float: left;
  width: 100px;
  height: 100px;
  background-color: orange;
  margin-left: -100px;
}

实例地址: http://codepen.io/anon/pen/adMGer 兼容性: IE6+ 缺点:和上面的方案相比,html代码结构更加复杂。所以我们按需选择自己需要的方案吧

3.圣杯布局

圣杯布局在结构上要简单一点,也能够让主列优先加载。 实现原理:

  1. 添加一个包裹框,设置padding-left``padding-right值,比子列宽度大一个空隙的宽度。
  2. 主列,子列都设置为float: left 左子列margin-left设置为-100%,并且设置为position:relative; left: -110px将左子列放置到左侧。右子列同理。
  3. 主列只需设置宽度为100%即可。包裹框的宽度不要设置为100%,自适应即可。

html代码如下

<div class="wrapper">
  <div class="main"></div>
  <div class="left"></div>
  <div class="right"></div>
</div>

css代码如下

.wrapper {
  padding-left: 110px;
  padding-right: 110px;
  overflow: hidden;
}
.main {
  float: left;
  width: 100%;
  height: 100px;
  background-color: #ccc;
}
.left {
  float: left;
  width: 100px;
  height: 100px;
  margin-left: -100%;
  position: relative;
  left: -110px;
  _left: 0;
  background-color: orange;
}
.right {
  float: left;
  width: 100px;
  height: 100px;
  background-color: orange;
  margin-left: -100px;

  position: relative;
  right: -110px;
}

实例地址:http://codepen.io/anon/pen/xZBJQp 兼容性:IE6+ 只是和双飞翼布局上有一些细节的区别。总体来说差别不大。