其实两个布局实现的效果是一样的,两边定宽中间自适应,只不过用到的方法略有不同。
1. 双飞翼布局
先看html结构,和圣杯布局不同之处在于自适应元素内部又包了一个div,作用后序在代码中讲解:
<div id="content">
<!-- 自适应元素至于顶层,否则其他元素位置错乱,因为margin-left时必须按这个顺序 -->
<div class="main">
<div class="wrap">main</div>
</div>
<div class="aside">aside</div>
<div class="extra">extra</div>
</div>
再来看CSS代码,逐步分析
content设置个边框用于标识,不设置宽和高默认宽填满高为0。然后提前写好清除浮动代码。
#content {
border: 1px solid #999;
}
#content:after {
content: '';
display: block;
clear: both;
}
给三块区域都设置浮动,使得后面margin-left的盒子可以根据前一个浮动的盒子来移动,。
.main,
.aside,
.extra {
float: left;
}
main区域设置宽度为100%占满一行,同时设置高度撑开content盒子(因为上面清除了浮动),再通过内部的wrap的margin值来撑开左右两边留给aside和extra进来。
.main{
width: 100%;
}
.wrap{
background-color: lightskyblue;
margin-left: 100px;
margin-right: 100px;
height: 300px;
}
aside区域设置宽度要等于wrap之前margin出来的宽度,然后关键还是这个margin-left:-100%,因为这里的margin-left是相对于前一个浮动的盒子也就是main而言的,因此-100%对应的也是main的宽度,如图:
注意图中浅蓝色是wrap的宽度,main是占满整行的所以把aside和extra挤下来了
.aside{
width: 100px;
height: 300px;
background-color: aquamarine;
margin-left: -100%;
}
那么接下来要把extra移到右边空白处,此时extra前一个浮动的盒子还是main,那么只要移动自身的宽度就能放进去了,也就是-100px
.extra{
width: 100px;
height: 300px;
background-color: cornflowerblue;
margin-left: -100px;
}
2. 圣杯布局
先看html结构,相较于双飞翼简洁一点。
<div id="content">
<!-- 自适应元素至于顶层,否则其他元素位置错乱 -->
<div class="main">main</div>
<div class="aside">aside</div>
<div class="extra">extra</div>
</div>
再看CSS,首先从content开始就不一样了,这里的content需要通过padding流留出左右两块空白来放aside和extra,而且这里还需要设置min-width避免布局混乱,然后也要清除浮动。
如果不设置min-width,把整个页面的宽度收缩后,会出现布局错乱的效果,因为当页面收缩时,main因为是其父容器content的100%的宽度,所以main也会跟着收缩,当main收缩到比aside宽度还要小,这时候父容器ct的100%宽度<aside的宽度,就不能容纳aside,所以将其挤到了下一行。
#content {
border: 1px solid #999;
padding-left: 100px;
padding-right: 100px;
min-width: 200px;
}
#content::after {
content: '';
display: block;
clear: both;
}
然后盒子全部浮动这里是一样的
.main,
.aside,
.extra {
float: left;
}
然后先看main盒子,设置高度撑开盒子,然后设置宽度占满一行
.main {
background: lightskyblue;
height: 300px;
width: 100%;
}
然后是aside盒子,这里设置margin-left:-100%前是这样的,和上面双飞翼布局有所差异,因为main盒子宽度不一样了:
设置margin后会发现位置不对
再通过定位的方式左移100px即可
.aside {
background: lightgreen;
width: 100px;
height: 300px;
margin-left: -100%;
position: relative;
left: -100px;
}
那么extra也是同理了,就不用再作过多解释
.extra {
background: yellow;
width: 100px;
height: 300px;
margin-left: -100px;
position: relative;
left: 100px;
}
3. flex
使用flex实现是最简单方便的,因为flex:1这个属性可以自动撑满剩余部分:
<body>
<main>
<div class="left">left</div>
<div class="middle">middle</div>
<div class="right">right</div>
</main>
</body>
<style>
main{
display: flex;
height: 500px;
}
.left , .right{
width: 200px;
background-color: lightgreen;
}
.middle{
flex: 1;
background-color: lightblue;
}
</style>