面试高频考点,以前就记了个比较有名的圣杯布局,没想到面试官问了我上下栏固定、中间自适应的布局,措手不及。借此弥补下CSS布局方面的知识。css
(如下代码我都在浏览器上跑过,基本可以实现布局要求。)html
在网上找了下关于上中下布局的文章,发现资料不多,因此总结的不是很好,若是你们有更完整、更优美的办法能够在评论区留言。面试
<div class="top-center-bottom">
<div class="top">top</div>
<div class="center">center</div>
<div class="bottom">bottom</div>
</div>
复制代码
.top-center-bottom>div{
position:absolute;
}
.top{
top:0;
height:100px;
width:100%;
background:red;
}
.bottom{
bottom:0;
height:100px;
width:100%;
background:red;
}
.center{
bottom:100px;
top:100px;
width:100%;
overflow: auto;
background:green;
}
复制代码
overflow
属性规定当内容溢出元素框时发生的事情。浏览器
overflow: auto;
若是内容被修剪,则浏览器会显示滚动条以便查看其他的内容。overflow: hidden;
内容会被修剪,而且其他内容是不可见的。布局
.top-center-bottom{
display: flex;
height: 100%; /*要指定高度*/
flex-direction: column; /*布局从上到下排列*/
}
.top,.bottom{
display: flex; /*这是为居中 文字的*/
justify-content: center; /*文字 水平居中*/
align-items: center; /*文字垂直居中*/
}
.top{
height: 100px;
background: #665aa4;
}
.center{
flex-grow: 1; /*不知道和 flex: 1 有啥区别*/
text-align: center;
background: #3dc95d;
}
.bottom{
height: 100px;
background: #fc430b;
}
复制代码
flex-direction:colum;
使总体布局从上到下排列flex
flex-grow:1;
应用于main,使得main自动填充剩余空间spa
flex-grow
的使用避免了当main内容过少时footer部分会被提高到页面上方的问题(传统方式上可能须要靠绝对定位来解决了~)3d
其余可作参考的写法:code
<div class="container">
<div class="flex-item">
<div style="height: 100px;line-height: 100px;">top</div>
</div>
<div class="flex-item">
<div style="height: 800px;color: #fff;">
<div class="center">center</div>
</div>
</div>
<div class="flex-item">
<div style="height: 100px;line-height: 100px;">bottom</div>
</div>
</div>
复制代码
html, body{
height:100%;
margin: 0;
padding: 0;
}
.container{
height: 100%;
display: flex;
flex-direction: column;
text-align: center;
}
.flex-item:nth-child(1), flex-item:nth-child(3){
flex-grow:0;
flex-shrink: 0;
background-color: #ababab;
}
.flex-item:nth-child(2){
flex-grow:1;
flex-shrink: 1;
background-color: #000;
overflow-y: auto;
}
.center{
position: fixed;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -24px;
}
复制代码
flex
属性是flex-grow, flex-shrink 和 flex-basis
的简写,默认值为0 1 auto
。 flex-basis
指定了 flex 元素在主轴方向上的初始大小。htm
该属性有两个快捷值:
auto (1 1 auto)
:元素会根据自身的宽度与高度来肯定尺寸none (0 0 auto)
:元素会根据自身宽高来设置尺寸
由于太多了我也记不住,记住前两个经常使用的应该就能够了。
<div class="left">Left</div>
<div class="main">Main</div>
<div class="right">Right</div>
复制代码
<!--简单的进行CSS reset-->
body,html{
height:100%;
padding: 0px;
margin:0px;
}
<!--左右绝对定位-->
.left,.right{
position: absolute;
top:0px;
background: red;
height:100%;
}
.left{
left:0;
width:100px;
}
.right{
right:0px;
width:200px;
}
<!--中间使用margin空出左右元素所占据的空间-->
.main{
margin:0px 200px 0px 100px;
height:100%;
background: blue;
}
复制代码
缺点:若是中间栏含有最小宽度限制,或是含有宽度的内部元素,当浏览器宽度小到必定程度,会发生层重叠的状况。
<div class="container">
<!-- 优先渲染 -->
<div class="center">
center
</div>
<div class="left">
left
</div>
<div class="right">
right
</div>
</div>
复制代码
使三栏浮动,并相对定位,给左右两个容器设置200px的宽度、中间的容器设置100%的宽度。
body,html {
height:100%;
padding: 0;
margin: 0
}
.container {
padding: 0 200px;
height: 100%;
}
.container > div {
position: relative;
float: left;
height: 100%;
}
.center {
width: 100%;
background-color: red;
}
.left {
width: 200px;
left: -200px;
margin-left: -100%;
background-color: green;
}
.right {
width: 200px;
right: -200px;
margin-left: -200px;
background-color: blue;
}
复制代码
步骤:
margin-left: -100%
便可使左侧栏浮动到 center 上面,并位于 center 左侧之上。margin-left: -200px
,这里的长度等于 right 的长度padding: 0 200px
left: -200px; right: -200px
,往两侧分别偏移自身的宽度去覆盖掉 contaniner 使用padding后的空白位置。相关解释以下:
缺点:在窗口变小到限定值时布局会乱掉,须要给它加上一个宽度限制min-width。并且圣杯布局实际看起来是复杂的后期维护性也不是很高,在淘宝UED的探讨下,出来了一种新的布局方式就是双飞翼布局。
双飞翼布局给center 部分包裹了一个main,经过设置margin主动地把页面撑开,为左右两栏div留出位置。这时窗口宽度太小时就不会出现混乱的状况了。
<!-- 优先渲染 -->
<div class="center">
<div class="inner">
center
</div>
</div>
复制代码
body,html {
height:100%;
padding: 0;
margin: 0
}
.container {
height: 100%;
}
.container > div{
float: left;
height: 100%;
}
.center {
width: 100%;
background-color: red;
}
.left {
width: 200px;
margin-left: -100%;
background-color: green;
}
.right {
width: 200px;
margin-left: -200px;
background-color: blue;
}
/*新增*/
.inner {
margin: 0 200px;
}
复制代码
圣杯和双飞翼布局的不一样在于解决“中间栏div内容不被遮挡”问题的思路不同:
圣杯布局为了中间div内容不被遮挡,将父容器设置了左右padding-left
和padding-right
后,将左右两个div用相对布局position:relative
并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div;
双飞翼布局为了中间div内容不被遮挡,直接在中间div内部建立子div用于放置内容,在该子div里用margin-left
和margin-right
为左右两栏div留出位置。增长多一个div就能够不用相对布局了,只用到了浮动和负边距。
//注意元素次序
<div class="left">Left</div>
<div class="right">Right</div>
<div class="main">Main</div>
复制代码
body,html {
height:100%;
padding: 0;
margin: 0
}
<!--左栏左浮动-->
.left {
background: red;
width: 100px;
float: left;
height: 100%;
}
<!--中间自适应-->
.main {
background: blue;
height: 100%;
margin:0px 200px 0px 100px;
}
<!--右栏右浮动-->
.right {
background: red;
width: 200px;
float: right;
height: 100%;
}
复制代码
<div class="flex">
<div class="left">left</div>
<div class="main">middle</div>
<div class="right">right</div>
</div>
复制代码
.flex {
display: flex;
flex-flow: row;
}
.left{
width: 180px;
height: 100px;
background-color: red;
}
.main{
flex: 1;
height: 100px;
background-color: blue;
}
.right {
width: 200px;
height: 100px;
background-color: green;
}
复制代码
左中右布局的话记住三种应该就没问题了,圣杯和双飞翼布局须要理解,别像我面试的时候只憋出来一个圣杯,还忘了具体怎么实现......都是泪。
还有浏览器的适配问题,由于被问到了,头疼......你们有时间的话本身能够搜一下,以后有时间的话我再补充吧,应付面试的话以上方法应该就够了。