圣杯布局和双飞翼布局都是实现三栏布局的方法,左右定宽,中间自适应。与普通的三栏布局不同的是,这两种方式将main元素放在侧边栏的前面,以达到优先渲染的目,只是实现的方式略有不同。 下面以一个左边栏100px,右边栏120px的布局来说明。
通用步骤
HTML部分,用一个容器包裹起来,main在left、right前面:
<div class="container clearfix">
<div class="main">main</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
初始CSS部分,main、left、right全部左浮,main宽度为100%,清除浮动:
.container {
border: 1px solid black;
}
/* 清除浮动 */
.clearfix:after {
content: '';
display: block;
clear: both;
}
.main,.left,.right {
float: left;
}
.main {
background: #ccc;
width: 100%;
}
.left {
background: red;
width: 100px;
}
.right {
background: blue;
width: 120px;
}
此时,main占据一整行,left、right在第二行并排。接下来要将left和right上移,与main同一行。这里使用负margin能够实现。
.left {
background: red;
width: 100px;
margin-left: -100%;/* 值为100%,left会在最左边 */
}
.right {
background: blue;
width: 120px;
margin-left: -120px;/* 值为120px,即right的宽度right会在最右边 */
}
到这一步,三个元素已经并排在一行,但是有一个问题,left、right遮挡了部分main。解决这个问题有两种方法,分别对应圣杯布局和双飞翼布局。
圣杯布局
要解决遮挡,不如先"内部缩窄"container,然后再将left、right“推到合适的地方”。这里要使用相对定位,让left、right脱离文档流。
.container {
border: 1px solid black;
padding: 0 120px 0 100px;/*给左右padding,数值为对应左右宽度*/
}
.left {
background: red;
width: 100px;
margin-left: -100%;/* 值为100%,left会在最左边 */
position: relative;/* 相对定位,左移自身宽度 */
left: -100px;
}
.right {
background: blue;
width: 120px;
margin-left: -120px;/* 值为120px,即right的宽度right会在最右边 */
position: relative;
right: -120px;/* 相对定位,右移自身宽度 */
}
此时可以看到,left、right并没有遮挡住main。这时还需注意,当main宽度小于left宽度时,布局将会打乱。建议给container设置一个min-width值。
效果预览: jsbin.com/gihikon/11/…
双飞翼布局
要解决遮挡,也可以让main给left、right预留位置,“躲开”侧边栏占据的空间。不如给main添加一个容器元素wrap,再设置main的margin值避开侧边栏。 更改后的html:
<div class="container clearfix">
<div class="wrap">
<div class="main">main</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
/* 容器左浮 */
.wrap,.left,.right {
float: left;
}
/* 容器宽度100% */
.wrap {
background: #ccc;
width: 100%;
}
/* main左右margin分别为left、right的宽度 */
.main {
margin-left: 100px;
margin-right: 120px;
}
.left {
background: red;
width: 100px;
margin-left: -100%;/* 值为100%,left会在最左边 */
}
.right {
background: blue;
width: 120px;
margin-left: -120px;/* 值为120px,即right的宽度right会在最右边 */
}
此时left、right不需要定位,而且main的宽度为0也不会影响到布局,css也更为简单。
效果预览: jsbin.com/fagiyaq/4/e…
额外
都2019年了,还有什么布局是flex不能解决的呢?折腾来折腾去图个啥?
<div class="container">
<div class="main">main</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
.container {
border: 1px solid black;
display: flex;
}
.main {
background: #ccc;
flex: 1;
}
.left {
background: red;
width: 100px;
order: -1;
}
.right {
background: blue;
width: 120px;
}