面試高頻考點,以前就記了個比較有名的聖盃佈局,沒想到面試官問了我上下欄固定、中間自適應的佈局,措手不及。藉此彌補下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;
}
複製代碼
左中右佈局的話記住三種應該就沒問題了,聖盃和雙飛翼佈局須要理解,別像我面試的時候只憋出來一個聖盃,還忘了具體怎麼實現......都是淚。
還有瀏覽器的適配問題,由於被問到了,頭疼......你們有時間的話本身能夠搜一下,以後有時間的話我再補充吧,應付面試的話以上方法應該就夠了。