作者: zimo
segmentfault.com/a/1190000011358507
前言
現(xiàn)在,我們被稱為前端工程師玉凯。然而送火,早年給我們的稱呼卻是頁面仔〈醪瑁或許是職責越來越大夕玩,整體的前端井噴式的發(fā)展,使我們只關注了js惊豺,而疏遠了css和html燎孟。
其實,我們可能經(jīng)常在聊組件化尸昧,咋地咋地揩页。但是,回過頭來思考一下烹俗,如果你看到一張設計稿的時候碍沐,連布局都不清不楚,談何組件化呢衷蜓。所以,我們需要在分清楚組件之前尘喝,先來分清楚布局磁浇。廢話說了這么多,只是想告訴你朽褪,布局這個東西真的很重要置吓。本篇內容概括了布局的基礎+基本的PC端布局+移動端適配等內容无虚。如果你喜歡我的文章,歡迎評論衍锚,歡迎Star~友题。歡迎關注我的github博客
正文
或許對于你來說,喜歡js的背后戴质,是看不懂css的深層度宦。入門級的css非常簡單,但是告匠,精通它卻沒有想象的容易戈抄。我們本篇聊的是布局。前端開發(fā)后专,從拿到設計稿的那一刻划鸽,布局的思考就已經(jīng)開始了。
舉個例子戚哎,建筑師在設計房屋的時候裸诽,需要丈量開發(fā)地塊的長度,以及每幢房屋相對于其他房屋的位置型凳。
在css布局中丈冬,似乎也是這樣開始的。我們也會去區(qū)分每個元素的尺寸和定位啰脚,力爭完美的實現(xiàn)整個設計稿殷蛇。所以,我們的布局應該從定位和尺寸開始聊起
定位
定位的概念就是它允許你定義一個元素相對于其他正常元素的位置橄浓,它應該出現(xiàn)在哪里粒梦,這里的其他元素可以是父元素,另一個元素甚至是瀏覽器窗口本身荸实。還有就是浮動了匀们,其實浮動并不完全算是定位,它的特性非常的神奇准给,以至于它在布局中被人廣泛的應用泄朴。我們會在后文中專門提及它的。
談及定位露氮,我們就得從position屬性說起祖灰。你能準確的說出position的屬性值嗎?相信你可以完美地說出這么六個屬性值:static畔规、relative局扶、absolute、fixed、sticky和inherit三妈。
1畜埋、static(默認):元素框正常生成。塊級元素生成一個矩形框畴蒲,作為文檔流的一部分悠鞍;行內元素則會創(chuàng)建一個或多個行框,置于其父元素中模燥。
2咖祭、relative:元素框相對于之前正常文檔流中的位置發(fā)生偏移,并且原先的位置仍然被占據(jù)涧窒。發(fā)生偏移的時候心肪,可能會覆蓋其他元素。
3纠吴、absolute:元素框不再占有文檔流位置硬鞍,并且相對于包含塊進行偏移(所謂的包含塊就是最近一級外層元素position不為static的元素)
4、fixed:元素框不再占有文檔流位置戴已,并且相對于視窗進行定位
5固该、sticky:(這是css3新增的屬性值)粘性定位,官方的介紹比較簡單糖儡,或許你不能理解伐坏。其實,它就相當于relative和fixed混合握联。最初會被當作是relative桦沉,相對于原來的位置進行偏移;一旦超過一定閾值之后金闽,會被當成fixed定位纯露,相對于視口進行定位。demo地址(https://jsbin.com/moxetad/edit?html,css,output)
簡單地代芜,介紹一下position的屬性值的含義后埠褪,在來看一下偏移量top、right挤庇、bottom钞速、left四個屬性。
不清楚嫡秕,當初在初學css的時候渴语,會不會與margin這個屬性混淆?其實昆咽,它們之間是很容易去辨識地驾凶。因為這四個屬性值屠升,其實是,定位時的偏移量狭郑。偏移量不會對static的元素起到作用。而margin汇在,相對應的是盒子模型的外邊距翰萨,它會對每個元素框起到作用,使得元素框與其他元素之間產(chǎn)生空白糕殉。
下面:我們來看一下一些常用定位的偏移
1亩鬼、relative:它的偏移是相對于原先在文檔流中的位置,如圖:relative relative-offset
這里設置了top:100px阿蝶,left:100px雳锋。
2、absolute:它的偏移量是相對于最近一級position不是static的祖先元素的
3羡洁、fixed:它的偏移量是相對于視口的玷过。
其實,這里說描述的內容筑煮,應該都是需要理解的辛蚊。這些相對于布局來說是基礎的,同時也是非常重要的真仲。需要注意的是袋马,這里的偏移量其實已經(jīng)涉及到了接下來要說的尺寸。在做自適應布局設計時秸应,往往希望這些偏移量的單位能夠使用百分比虑凛,或者相對的單位例如rem等。
尺寸
那之前上面談到過尺寸的單位——百分比软啼。那么桑谍,下面部分我們就圍繞著尺寸單位展開。
尺寸焰宣,我們就應該從單位聊起霉囚,對于px這個單位,做網(wǎng)頁的應該在熟悉不過了匕积,因此不多做介紹盈罐。
那么,我們可以來介紹一下下面幾個單位:
1闪唆、百分比:百分比的參照物是父元素盅粪,50%相當于父元素width的50%
2、rem:這個對于復雜的設計圖相當有用悄蕾,它是html的font-size的大小
3票顾、em:它雖然也是一個相對的單位础浮,相對于父元素的font-size,但是奠骄,并不常用豆同,主要是計算太麻煩了。
單位只是一個來定義元素大小的相應參考含鳞。另一個概念影锈,或許可以用房子來打一個比方,在早年每幢房子都會在房子的外圍建一層柵欄蝉绷,使得整一塊地區(qū)可以看成房子+內部地塊+柵欄+外圍地塊的模型鸭廷。而在css中,每個元素也會有盒子模型的概念熔吗。
盒子模型:每個元素辆床,都會形成一個矩形塊,主要包括四部分:margin(外邊距)+border(邊框)+padding(內邊距)+content(內容)
css中存在兩種不同的盒子模型桅狠,可以通過box-sizing設置不同的模型讼载。兩種盒子模型,主要是width的寬度不同垂攘。如圖:
這是標準盒子模型维雇,可以看到width的長度等于content的寬度;而當將box-sizing的屬性值設置成border-box時晒他,盒子模型的width=border+padding+content的總和吱型。
可以看出,對于不同的模型的寬度是不同的陨仅。寬度默認的屬性值是auto津滞,這個屬性值會使得內部元素的長度自動填充滿父元素的width。如圖:
但是灼伤,height的屬性值也是默認的auto触徐,為什么沒有像width一樣呢?
其實狐赡,auto這個屬性值表示的是瀏覽器自動計算撞鹉。這種自動計算,需要一個基準颖侄,一般瀏覽器都是允許高度滾動的鸟雏,所以,會導致一個問題——瀏覽器找不到垂直方向上的基準览祖。
同樣地道理也會被應用在margin屬性上孝鹊。相信如果考察居中時,水平居中你可能閉著眼睛都能寫出來展蒂,但是垂直居中卻繞著腦袋想又活。這是因為如果是塊級元素水平居中只要將水平方向上的margin設置成auto就可以了苔咪。但是,垂直方向上卻沒有這么簡單柳骄,因為你設置成auto時团赏,margin為0。這個問題耐薯,還是需要仔細思考一下的馆里。
到此為止,布局最基本的部分我們已經(jīng)將去大半可柿,還有就是一塊浮動。
浮動
浮動丙者,這是一個非常有意思的東西复斥,在布局中被廣泛的應用。最初械媒,設計浮動時目锭,其實并不是為了布局的,而是為了實現(xiàn)文字環(huán)繞的特效纷捞,如圖:
但是痢虹,浮動并不是僅僅這樣而已。何為浮動主儡?浮動應該說是‘自成一派’奖唯,類似于ps中的圖層一樣,浮動的元素會在浮動層上面進行排布糜值,而在原先文檔流中的元素位置丰捷,會被以某種方式進行刪除,但是還是會影響布局寂汇。你可能會覺得有疑問病往,什么叫影響布局?我們可以來舉個例子:
首先骄瓣,我們準備兩個顏色塊停巷,如圖:
之后我們將left的塊設置成左浮動,如圖:
可以榕栏,發(fā)現(xiàn)雖然left塊因為左浮動畔勤,而使得原先元素在文檔流中占有的位置被刪除,但是臼膏,當right塊補上原先的位置時硼被,right塊中的字體卻被擠出來了。這就是所謂的影響布局渗磅。
浮動為什么會被使用在布局中呢嚷硫?因為設置浮動后的元素會形成BFC(使得內部的元素不會被外部所干擾)检访,并且元素的寬度也不再自適應父元素寬度,而是適應自身內容仔掸。這樣就可以脆贵,輕松地實現(xiàn)多欄布局的效果。
浮動的內容還需要介紹一塊——清除浮動起暮÷舭保可以看到,浮動元素负懦,其實對于布局來說筒捺,是特別危險的。因為你可能這一塊做過浮動纸厉,但未做清除系吭,那么造成高度塌陷的問題。就是上面圖示的那種情況颗品。
清除浮動肯尺,最常用的方法有兩種:
1、overflow: 將父元素的overflow躯枢,設置成hidden则吟。
2、after偽類:對子元素的after偽類進行設置锄蹂。
這里只是稍微的提上一嘴氓仲。下面我們正式來介紹一下網(wǎng)頁的布局,本篇最核心的東西得糜。
最初的布局——table
最初的時候寨昙,網(wǎng)頁簡單到可能只有文字和鏈接。這時候掀亩,大家最常用的就是table舔哪。因為table可以展示出多個塊的排布。
這種布局現(xiàn)在應該不常用了槽棍,因為在形色單一時捉蚤,使用起來方便。但是炼七,現(xiàn)在的網(wǎng)頁變得越來越復雜缆巧,適配的問題也是越來越多,這種布局已經(jīng)不再時候了豌拙。
主要是div塊的出現(xiàn)陕悬,可以使得網(wǎng)頁進行靈活的排布,使得網(wǎng)頁變得繁榮按傅。這時捉超,開發(fā)者也開始思索如何去更加清晰地分辨網(wǎng)頁的層次胧卤。接下來,我們可以看看有哪些比較出名的布局方式拼岳。
兩欄布局
是否記得枝誊,那些一邊主體內容,一邊目錄的網(wǎng)頁惜纸,如圖:
類似于上圖的布局叶撒,可以定義為兩欄布局。
兩欄布局:一欄定寬耐版,一欄自適應祠够。這樣子做的好處是定寬的那一欄可以做廣告,自適應的可以作為內容主體粪牲。
實現(xiàn)的方式:
float + margin:
<body>
? <div class="left">定寬</div>
? <div class="right">自適應</div>
</body>
.left{
??width:?200px;
??height:?600px;
??background:?red;
??float:?left;
??display:?table;
??text-align:?center;
??line-height:?600px;
??color: #fff;
}
.right{
??margin-left:?210px;
??height:?600px;
??background:?yellow;
??text-align:?center;
??line-height:?600px;
}
如圖所示:
其他的方法:還可以使用position的absolute哪审,可以使用同樣的效果
三欄布局
三欄布局,也是經(jīng)常會被使用到的一種布局虑瀑。
它的特點:兩邊定寬,然后中間的width是auto的滴须,可以自適應內容舌狗,再加上margin邊距,來進行設定扔水。
三欄布局可以有4種實現(xiàn)方式痛侍,每種實現(xiàn)方式都有各自的優(yōu)缺點。
1.使用左右兩欄使用float屬性魔市,中間欄使用margin屬性進行撐開主届,注意的是html的結果
<div class="left">左欄</div>
<div class="right">右欄</div>
<div class="middle">中間欄</div>
.left{
??width:?200px;height:?300px;?background:?yellow;?float:?left;????
}
.right{
??width:?150px;?height:?300px;?background:?green;?float:?right;
}
.middle{
??height:?300px;?background:?red;?margin-left:?220px;?margin-right:?160px;
}
缺點是:1. 當寬度小于左右兩邊寬度之和時,右側欄會被擠下去待德;2. html的結構不正確
2. 使用position定位實現(xiàn)君丁,即左右兩欄使用position進行定位,中間欄使用margin進行定位
<div class="left">左欄</div>
<div class="middle">中間欄</div>
<div class="right">右欄</div>
.left{
????background:?yellow;
????width:?200px;
????height:?300px;
????position:?absolute;
????top:?0;
????left:?0;
}
.middle{
????height:?300px;
????margin:?0?220px;
????background:?red;
}
.right{
????height:?300px;
????width:?200px;
????position:?absolute;
????top:?0;
????right:?0;
????background:?green;
}
好處是:html結構正常将宪。
缺點時:當父元素有內外邊距時绘闷,會導致中間欄的位置出現(xiàn)偏差
3. 使用float和BFC配合圣杯布局
將middle的寬度設置為100%,然后將其float設置為left较坛,其中的main塊設置margin屬性印蔗,然后左邊欄設置float為left,之后設置margin為-100%丑勤,右欄也設置為float:left华嘹,之后margin-left為自身大小。
<div class="wrapper">
? ? <div class="middle">
? ? ? ? <div class="main">中間</div>
? ? </div>
? ? <div class="left">
? ? ? ? 左欄
? ? </div>
? ? <div class="right">
? ? ? ? 右欄
? ? </div>
</div>
.wrapper{
????overflow:?hidden;??//清除浮動
}
.middle{
????width:?100%;
????float:?left;
}
.middle?.main{
????margin:?0?220px;
????background:?red;
}
.left{
????width:?200px;
????height:?300px;
????float:?left;
????background:?green;
????margin-left: -100%;
}
.right{
????width:?200px;
????height:?300px;
????float:?left;
????background:?yellow;
????margin-left: -200px;
}
缺點是:1. 結構不正確 2. 多了一層標簽
4. flex布局
<div class="wrapper">
? ? <div class="left">左欄</div>
? ? <div class="middle">中間</div>
? ? <div class="right">右欄</div>
</div>
.wrapper{
????display:?flex;
}
.left{
????width:?200px;
????height:?300px;
????background:?green;
}
.middle{
????width:?100%;
????background:?red;
????marign:?0?20px;
}
.right{
????width:?200px;
????height:?3000px;
????background:?yellow;
}
除了兼容性法竞,一般沒有太大的缺陷
三欄布局使用較為廣泛耙厚,不過也是比較基礎的布局方式强挫。對于PC端的網(wǎng)頁來說,使用較多颜曾,但是移動端纠拔,本身寬度的限制,很難做到三欄的方式泛豪。因此稠诲,移動端盛行的現(xiàn)在,我們應該掌握一些自適應布局技巧和flex等方式诡曙。
移動端的時代
或許柄错,手機占用了人們大部分的時間,對于前端工程師來說森瘪,不僅需要會h5和大前端的技術闯狱,還需要去適配不同的手機屏幕。PC端稱王的時代已經(jīng)過去慎璧,現(xiàn)在要求的網(wǎng)頁都是需要能夠去適配PC和移動端的床嫌。
之前,所聊的兩欄和三欄布局胸私,一般只能在PC中去使用厌处,在移動端,由于屏幕尺寸有限岁疼,很難去做到類似的操作阔涉,所以,我們需要來了解新的東西捷绒。
1. 媒體查詢
如果你需要一張網(wǎng)頁能夠在PC和移動端都能按照不同的設計稿顯示出來瑰排,那么你需要做的就是去設置媒體查詢。
媒體查詢的css標識符是@media暖侨,它的媒體類型可以分為:
1椭住、all, 所有媒體
2字逗、braille 盲文觸覺設備
3函荣、embossed 盲文打印機
4、print 手持設備
5扳肛、projection 打印預覽
6傻挂、screen 彩屏設備
7、speech ‘聽覺’類似的媒體類型
8挖息、tty 不適用像素的設備
9金拒、tv 電視
代碼示例:
@media?screen?{
??p.test?{font-family:verdana,sans-serif;font-size:14px;}
}
@media?print?{
??p.test?{font-family:times,serif;font-size:10px;}
}
@media?screen,print?{
??p.test?{font-weight:bold;}
}
/*移動端樣式*/
@media only screen?and?(min-device-width?:?320px)?and?(max-device-width?:?480px)?{
??/* Styles */
}
媒體查詢的主要原理:它像是給整個css樣式設置了斷點,通過給定的條件去判斷,在不同的條件下绪抛,顯示不同的樣式资铡。例如:手機端的尺寸在750px,而PC端則是大于750px的幢码,我們可以將樣式寫成:
@media screen?and?(min-width:?750px){
??.media{
????height:?100px;
????background:?red;
??}
}
@media?(max-width:?750px){
??.media{
????height:?200px;
????background:?green;
??}
}
demo地址(https://jsbin.com/gopezum/edit?html,css,output)
效果圖:
flex彈性盒子
其實移動端會經(jīng)常使用到flex布局笤休,因為在簡單的頁面適配方面,flex可以起到很好的拉伸的效果症副。我們先看幾張圖體會一下:
可以從圖中看出店雅,這個網(wǎng)頁不管屏幕分辨率怎么發(fā)生變化,它的高度和位置都不變贞铣,而且里面的元素排布也沒有發(fā)生變化闹啦,總是圖標信息在左邊和薪資狀況在右邊。
這就是很明顯的辕坝,flex布局窍奋。flex可以在移動端適配比較簡單的,元素比較單一的頁面酱畅。
具體的flex布局內容琳袄,在這里不詳細說明。flex傳送門
rem適配
rem可以說是移動端適配的一個神器纺酸。類似于手淘等界面窖逗,都是使用的rem進行的適配。這種界面有個特點就是頁面元素的復雜度比較高吁峻,而使用flex進行布局會導致頁面被拉伸,但是上下的高度卻沒有變化等問題在张。示例圖:
具體的講解可以看這篇比較好的文章用含。rem傳送門(http://www.cnblogs.com/lyzg/p/4877277.html)
總結
分析到這里,布局的很多東西都已經(jīng)非常的清晰了帮匾。相信這是一篇值得去收藏的一篇文章啄骇。內容可能有點多,所以這里做一個總結:
1瘟斜、定位
2缸夹、尺寸
3、浮動
4螺句、最初的布局——table
5虽惭、兩欄布局
6、三欄布局
7蛇尚、移動端的布局
相信你看完這些芽唇,在以后,一定可以拿到設計稿的時候,內心大致有個算盤匆笤,應該如何區(qū)分研侣,如何布局。
感興趣的小伙伴炮捧,可以關注公眾號【grain先森】庶诡,回復關鍵詞 “小程序”,獲取更多資料咆课,更多關鍵詞玩法期待你的探索~