面试的时候经常会被问到这个题目,以及我们在平常做界面的时候也会遇到这种三栏布局的要求,那么如何实现呢?其实网上有很多方法,但还是跟着我的例子敲一遍代码吧,这样自己才能知道原理是什么,也有助于理解。
一、圣杯布局(让left和right占据container的padding)
html界面:分别是左中右的三个div
<div class="container">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>
1、给center、left、right分别设置宽度。(由于三个部分都是div,是块级元素,所以每个元素都从新的一行开始)其实现的效果是center占满了宽度,left和right分别另起一行。
.center{
background-color:red;
width:100%;
}
.left{
background-color:green;
width:200px;
}
.right{
background-color:blue;
width:200px;
}
2、为了让三个部分都处在一行中,给他们设置float:left。(这样就会根据元素的宽度先进行一行的占位,当宽度不够时才另起一行,这也解释了为什么left和right会在第二行上)
.container>div{
float:left;
}
3、 因为center的宽度是100%,所以将left和right挤到了下一行。如何把left和right放到和center同一行?分别给left和right设置margin-left:-100%, margin-left:right的宽度。(margin-left为负值说明向左移动指定的长度)
.left{
background-color:green;
width:200px;
margin-left:-100%
}
.right{
background-color:blue;
width:200px;
margin-left:-200px
}
有人会问了,left向左移动100%的宽度到达第一行的左侧是可以理解的,那为什么right仅需要向左移动200px而不是400px呢?
其实这个问题是我最开始的疑问,因为这个其实是有先后顺序的,当left向左移动了100%后,right就在第二行中以最左侧为起点了,如下图所示,所以再将right向左移动200px就可以啦。
4、此时,center中的部分内容被左右两个div覆盖了。因此给外层的container设置padding:0 200px(使整个container横向向中间缩了200px,),overflow:hidden(隐藏掉超出div框的内容)
.container{
padding:0 200px;
}
5、将left和right再分别向两边移动,占据上一步留出来的左右两边空白。分别设置left:-200px,right:-200px;(光设置这两项发现left和right还是没有移动,原因是positon默认值是static,当 "position" 属性的值为 "static",那么设置 "left" 属性不会产生任何效果。)
.left{
background-color:green;
width:200px;
margin-left:-100%;
left:-200px;<!--向左移动200px-->
}
.right{
background-color:blue;
width:200px;
margin-left:-200px;
right:-200px;<!--向右移动200px-->
}
6、将lelft和right的position设置为relative,即相对自己原来的位置进行偏移。当设置left:-200px时,即把该div的左边缘设置在其原来位置的左边缘的左侧200px。
.container>div{
float:left;
position:relative;
}
二、双飞翼布局(让left和right占据center里层的margin)
和圣杯布局的不同点在于如何解决center的两侧被遮挡的问题。采用在center里加一层content。给content设置margin来让left和right占据content的margin部分,从而做到不遮挡文字内容。(写以下代码也能实现上图效果)
1、html结构
<div class="container">
<div class="center">
<div class="content">centereeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
2、 设置content的样式
.content{
margin-left:200px;
margin-right:200px;
}
三、flex布局
1、设置基本html结构:container里包括left、center、right。
<div class="container">
<div class="left">left</div>
<div class="center">centereeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee </div>
<div class="right">right</div>
</div>
2、 根据要求设置left和right的定宽为200px。实现效果为根据html结构中三者的顺序进行顺序渲染,left和right各占200px,center占一整行。
.left{
width:200px;
background-color:blue;
}
.center{
background-color:red;
}
.right{
width:200px;
background-color:green;
}
3、采用flex布局,给外层的container设置display:flex。同时给center设置flex:1 1 auto(flex-grow:1设置item的放大比例,为1表示当存在剩余空间时会放大;flex-shrink:1表示item的缩小比例,为1表示当空间不足时会缩小。)
.container{
display: flex;
flex-direction:row;
}
.center{
background-color:red;
flex:1 1 auto;
}
四、绝对定位布局
(优点是简单,缺点就是,绝对定位是脱离文档流的,意味着下面的所有子元素也会脱离文档流)
1、给外层container加上positon:relative(因为positon:absolute生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。)
.container{
position:relative;
}
2、给左中右三者设置positon:absolute,并精确三者相对于top left和right的距离。
.container > div{
position:absolute;
}
.left{
background-color:red;
width:200px;
top:0;
left:0;
}
.right{
background-color:green;
width:200px;
top:0;
right:0;
}
.center{
background-color:blue;
width:100%;
top:0;
left:200px;
right:200px;
}
五、float布局
(浮动布局的优点就是比较简单,兼容性也比较好。但需要做清除浮动)
1、html结构,注意一定是左右中的布局;给left和right加定宽200px。
.left{
background-color:green;
width:200px;
}
.right{
background-color:red;
width:200px;
}
2、给left设置float:left和right设置float:right即可实现要求。
.left{
background-color:green;
width:200px;
float:left;
}
.right{
background-color:red;
width:200px;
float:right;
}
补充:为什么是左中右的布局呢?
- 浮动元素有一个规则:当非浮动元素和浮动元素同时存在且非浮动元素在前,那么浮动元素不会高于非浮动元素,即浮动和非浮动会按页面上下顺序排列。将center放在最前面的效果如下:(两个浮动元素left和right不会超过非浮动元素center)
- 因为div是块级元素,默认的宽度是100%,即它的父级元素container的宽度,此时为浏览器的宽度。
六、Table-Cell布局
(缺点是当某一个单元格的高度超出的时候,两侧的单元格也会一起变高)
1、html结构:左中右的布局,左右固定宽度200px。
.left{
background-color:red;
width:200px;
}
.right{
background-color:green;
width:200px;
}
.center{
background-color:lightblue;
}
2、将外层container设置display:table。将左中右设置display:table-cell。此时确实是三栏布局,只不过center的宽度为内容的宽度。并没有自适应浏览器中剩余的宽度。
.container{
display:table;
}
.container > div{
display:table-cell;
}
3、为了让center的宽度自适应,设置为100%。结果是center的宽度是撑开了,但是left和right的宽度确被挤压到只有内容的宽度了。
.center{
background-color:lightblue;
width:100%;
}
4、为了解决left和right的宽度不被挤压的问题,给二者分别设置min-width:200px。结果便能实现预期效果。
.left{
background-color:red;
width:200px;
min-width:200px;
}
.right{
background-color:green;
width:200px;
min-width:200px;
}
七、网格布局
1、将container配置为display:grid,grid-template-columns:200px auto 200px。
(grid-template-columns 用来把网格指定列的宽度;grid-gap 用来指定列(或行)的间距)
.container{
display:grid !impornant
grid-template-columns:200px auto 200px;
grid-gap:5px
}
有一个问题就是给外层的container设置display:grid和flex时,浏览器的默认样式总是覆盖掉我自己写的样式,这个要怎么处理呢?
第一、不太清除为什么浏览器默认的样式会覆盖掉自己写的样式,而且没有语法错误。
第二、采用了!impornant给我自己设置的display加了最高优先级
不知道小伙伴儿们有没有遇到过这种情况的,欢迎大家一起来讨论呀。