Web自适应布局你需要知道的所有事儿
有這樣一個問題。
請說說你知道的所有web布局方式?
一般來說,有以下這些布局方法:
有小伙伴就要說,這也太多了吧,我應該怎么選擇?
別急,下面我們就開始逐一分析各種方法在web自適應布局下的使用姿勢,最后做個總結。
本文的所有例子使用了同一種三欄布局。源代碼點我
- 大尺寸 width > 1024px
- 中尺寸 768px < width < 1024px
- 小尺寸 width < 768px
1. 浮動布局 float:left|right
最常用的布局方式之一,設置了float的元素脫離了文檔流。需要注意在使用過浮動后,需要清除浮動,從而避免影響后面的非浮動元素。
HTML
<div class="rwd-header">Header</div> <div class="rwd-content"><div class="rwd-content-left">Left</div><div class="rwd-content-body"><div class="rwd-content-bodyTop">Top Content</div><div class="rwd-content-bodyBottom">Bottom Content</div></div><div class="rwd-content-right">Right</div> </div> <div class="rwd-footer">Footer</div> 復制代碼普通的html布局,一個header,一個footer,中間是三欄式布局。
關鍵css
.rwd-content-left, .rwd-content-body, .rwd-content-right {float: left; } 復制代碼給中間的三欄都設上浮動。
.rwd-content::after {content: "";clear: both;display: block; } 復制代碼清除浮動
.rwd-content-left {width: 20%;height: 200px; }.rwd-content-body {width: 60%; }.rwd-content-right {height: 300px;width: 20%; } 復制代碼元素的寬度都是百分比。因為沒有內容高度給死了,日常應用時多用auto,讓里面的內容撐開高度。
@media查詢
當@media的查詢條件滿足時,應用{}中的樣式。
screen就是指電腦屏幕,還有print指打印頁面。 MDN @media
@media做的事完全可以用javascript代替,用js添加一個class或者直接用js修改css屬性。優點是瀏覽器全兼容,缺點就是用了js。
@media only screen and (max-width: 1024px) {.rwd-content-left {width: 30%;}.rwd-content-body {width: 70%;}.rwd-content-right {width: 100%;} }@media only screen and (max-width: 768px) {[class*="rwd-content-"] {width: 100%;} } 復制代碼
中尺寸屏幕要把right擠下去,只要讓left和content加起來等于100%,后面的東西就自動換行了。
小尺寸用了css選擇器,把所有rwd-content-開頭的class寬度都設成100%。
親自試一試
2. inline-block display:inline-block
HTML
<div class="rwd-header">Header</div> <div class="rwd-content"><div class="rwd-content-left">Left</div><div class="rwd-content-body"><div class="rwd-content-bodyTop">Top Content</div><div class="rwd-content-bodyBottom">Bottom Content</div></div><div class="rwd-content-right">Right</div> </div> <div class="rwd-footer">Footer</div> 復制代碼html和浮動布局的一樣,為了避免空白字符壓縮(white space collapse)的問題,寫法略有變化。
關鍵css
.rwd-content-left, .rwd-content-body, .rwd-content-right {display: inline-block;vertical-align: top; } 復制代碼對我們這個布局,只是把float:left改成這兩句。
自適應的代碼也和float一樣,不重復貼了。
親自試一試
Float vs. Inline-block
兩者都是很常用的布局方式。
-
如果需要垂直居中,使用inline-block。
-
inline-block有空白字符壓縮的問題。
-
使用float,注意要清除浮動。
-
沒有特別推薦用哪種,看個人習慣。
如何調整float或inline-block布局中元素的順序?
比如我在小尺寸的時候,想把content放最上面,left和right都擠下去,怎么做呢?
float和inline-block布局沒有純css的方法,要用js把dom扣出來,往后面放,flexbox和grid布局都可以很好地解決這個問題。
3. flexible box display:flex
HTML
<div class="rwd-header">Header</div> <div class="rwd-content"><div class="rwd-content-left">Left</div><div class="rwd-content-body"><div class="rwd-content-bodyTop">Top Content</div><div class="rwd-content-bodyBottom">Bottom Content</div></div><div class="rwd-content-right">Right</div> </div> <div class="rwd-footer">Footer</div> 復制代碼html還是一樣。
看css前先說說flex基礎。
* flexbox兩分鐘不完全指北
flexbox布局說白了就是點菜。先想好要吃什么,然后點必選菜,最后點可選菜,愛點不點。
先想要吃什么,還是用之前的例子。header和footer不用管,需要布局一個這樣的東西:
然后點必選菜,有下面幾個必選菜要點:
1). flex-direction, 選水平方向從左到右,選flex-direction: row
.container {flex-direction: row | row-reverse | column | column-reverse; } 復制代碼2). flex-wrap,我們是單行布局,不要換行,選flex-wrap: nowrap
.container{flex-wrap: nowrap | wrap | wrap-reverse; } 復制代碼3). justify-content,如果水平方向有空間,怎么分配,選space-between
.container {justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly; } 復制代碼4). 垂直方向怎么布局,選align-items: flex-start
.container {align-items: flex-start | flex-end | center | baseline | stretch; } 復制代碼5). align-content,多行布局怎么分配空間,我們是單行布局,不存在的
.container {align-content: flex-start | flex-end | center | space-between | space-around | stretch; } 復制代碼選好這5個之后,再加上display: flex;,往flex容器上一寫,就完事了。
可以偷懶的地方: 上面5種屬性,第一個值是默認值,如果選了第一個,這個屬性可以不用寫。
最后的可選菜比較常用的是可以調整flex子項(flex item)的順序(order),單獨改變某個子項的布局等。
詳細教程點這里: flexbox中文教程[1]A Guide to Flexbox[2]
關鍵css
.rwd-content {display: flex;justify-content: space-between;align-items: flex-start; } 復制代碼flex容器(container)屬性如前文所說。
@media only screen and (max-width: 1024px) {.rwd-content {flex-wrap: wrap;}.rwd-content-left {width: 30%;}.rwd-content-body {width: 70%;}.rwd-content-right {width: 100%;} }@media only screen and (max-width: 768px) {[class*="rwd-content-"] {width: 100%;} } 復制代碼自適應布局時,設flex-wrap: wrap;,其他一樣。
親自試一試
Flexbox vs. Float/Inline-block
- 如果瀏覽器沒問題,flexbox可以替代(或者替代大多數)float和inline-block。
- 相比float,flexbox解決了垂直居中的問題。
- 相比float/inline-block,flexbox多了垂直布局的方式,可以使容器中的內容等高,還可以改變內容的順序。
- flexbox就像名字一樣,非常靈活,同一種布局都可以用多種方式實現。
- flexbox的缺點是需要記的屬性比較多,小部分瀏覽器支持不好。
Can I use flex ?
4. grid布局 display:grid
HTML
<div class="rwd-grid"><div class="rwd-header">Header</div><div class="rwd-content-left">Left</div><div class="rwd-content-bodyTop">Top Content</div><div class="rwd-content-bodyBottom">Bottom Content</div><div class="rwd-content-right">Right</div><div class="rwd-footer">Footer</div> </div> 復制代碼grid的特點就是為所欲為,dom的順序無所謂,只要放在grid容器下就可以。
看css之前還是先說說grid基礎。
* grid兩分鐘+兩分鐘不完全指北
2個兩分鐘因為一般grid有兩種使用方式:
1). 網格項(grid item)起個名字,在網格容器(grid container)上定義好網格布局并且通過名字指定好所有網格項的位置。
2). 網格容器只定義布局,每個網格項在使用的時候,自行選擇放到哪個(或哪幾個)網格中。
不管哪種方式,只要會劃線,你就掌握了grid布局。把想要的布局畫出來,然后用線分割開。
橫向1 ~ 7的黑線和縱向1) ~ 4)的紅線都叫網格線。
網格線包圍的一個或多塊矩形區域叫網格區塊。
第一種grid布局方式:
.rwd-grid {display: grid;grid-gap: 5px;width: 100%;grid-template-areas: "header header header""left top right""left bottom right"". bottom right"". bottom .""footer footer footer";grid-template-rows: 80px 150px 50px 100px 100px 100px;grid-template-columns: 20% 60% 20%; }.rwd-header {grid-area: header; } .rwd-content-left {grid-area: left; } .rwd-content-bodyTop {grid-area: top; } .rwd-content-bodyBottom {grid-area: bottom; } .rwd-content-right {grid-area: right; } .rwd-footer {grid-area: footer; } 復制代碼網格項(grid item)用grid-area屬性起個名字。
網格容器(grid container)上三個主要屬性要設置:
grid-template-areas: 就是一張地圖,和我們劃線分割的圖布局一樣,.表示空白。
grid-template-rows: 設置行上的高度,不設置的話為auto。除了固定數字,百分比還有fr。 grid-template-rows: repeat(3, 1fr)就是三等分的意思。
grid-template-columns: 設置列的寬度。
自適應布局就是重畫地圖。
@media only screen and (max-width: 1024px) {.rwd-grid {grid-template-areas: "header header""left top""left bottom"". bottom""right right""footer footer";grid-template-rows: 80px 150px 50px 200px 100px 100px;grid-template-columns: 30% 70%;} }@media only screen and (max-width: 768px) {.rwd-grid {grid-template-areas: "header""left""top""bottom""right""footer";grid-template-rows: 80px 200px 150px 250px 100px 100px;grid-template-columns: 100%;} } 復制代碼親自試一試1
第二種grid布局方式:
.rwd-grid {display: grid;grid-gap: 5px;margin: 5px 0;width: 100%;grid-template-rows: 80px 150px 50px repeat(3, 100px);grid-template-columns: 20% 60% 20%; } 復制代碼網格容器上只要設置grid-template-rows和grid-template-columns。網格項在用的時候,自行設置需要放的地方。有很多種設置方式。
.rwd-header {grid-column-start: 1;grid-column-end: 4;grid-row-start: 1;grid-row-end: 2; } 復制代碼四個屬性,分別是行、列的開始和結束。這邊的序號指的是網格線,參照之前圖中橫向的黑色網格線和縱向的紅色網格線。
參照圖,應該好理解。
相當于:
.rwd-header {grid-column: 1 / 4;grid-row: 1 / 2; } 復制代碼簡寫成兩個屬性,<開始> / <結束>。
相當于:
.rwd-header {grid-column: 1 / span 3;grid-row: 1; } 復制代碼span 3指的是經過了3個網格;如果網格項只跨越了1格,可以省略設置結束位置的網格線。
相當于:
.rwd-header {grid-area: 1 / 1 / 2 / 4; } 復制代碼網格線上左下右的順序,不同于margin和padding的上右下左。
當然你可以別管這么多亂七八糟的,看我自適應布局:
@media only screen and (max-width: 1024px) {.rwd-grid {grid-template-rows: 80px 150px 50px 200px 100px 100px;grid-template-columns: 30% 70%;}.rwd-header {grid-area: 1 / 1 / 2 / 3;}.rwd-content-left {grid-area: 2 / 1 / 4 / 2;}.rwd-content-bodyTop {grid-area: 2 / 2 / 3 / 3;}.rwd-content-bodyBottom {grid-area: 3 / 2 / 5 / 3;}.rwd-content-right {grid-area: 5 / 1 / 6 / 3;}.rwd-footer {grid-area: 6 / 1 / 7 / 3;} } 復制代碼親自試一試2
詳細教程點這里: 網格中基于線的定位[3]和這里 網格模板區域[4]
Grid vs. Flexbox
- flexbox是單方向的,橫向或者縱向,grid是二維的。
- grid就是可以為所欲為,甚至和html的順序沒有關系,只要扔到grid容器里就可以。
- grid能做到flexbox做不到的事,反之亦然。如果瀏覽器支持,最好結合兩者使用。
- grid適合布局大的骨架,flexbox適合布局局部。
- grid的最大缺點是瀏覽器支持不是很好。
- grid另一個缺點是,如果要往現有的布局里加一點或者刪一點東西,基本就是重畫了,其實也不算缺點,因為重畫很快。
- grid不適合復雜的布局,因為網格線太多我頭暈。
- grid小技巧,用chrome和firefox的調試工具查看grid容器可以看到網格,光看代碼要瘋。
Can I use grid ?
5. 絕對、相對定位 position:absolute|relative
相當常用,特別是各種特效里都會用到。
對于自適應布局,就自己算top和left吧。
6. 表格 <table>或display:table
個人認為表格布局比較適用于表格(看上去是廢話,但并不是)。
如果是一般的頁面布局,就不要用table了。Why not use tables for layout in HTML?[5]
關于表格的自適應,看這里:Responsive table layout[6]
7. 使用框架布局 bootstrap、Pure.css等
所謂萬變不離其宗,用框架布局也是使用了上面所說的原理,這邊就不再細說各種框架。
* IE盒模型
推薦給所有元素加上border-box;。
* {box-sizing: border-box; } 復制代碼IE盒模型的寬度和高度包括了padding和border,這樣對于百分比的布局比較好控制,不會出現加起來超過100%而換行的情況。
* 盡量不使用固定高度、寬度
在自適應的布局中少用或者不用固定的高度、寬度,使用百分比, auto或calc()。
* viewport
<meta name="viewport" content="width=500, initial-scale=1"> 復制代碼viewport主要用于手機自適應布局,因為現在手機分辨率越來越高,web上的1px到手機上未必就是1px,用這個meta讓手機的px和web的px保持一致。
具體解釋在這里: viewport meta[7]
說到這里,看完的同學應該都明白了web自適應布局常見的套路。
當碰到某個酷炫的自適應頁面的時候至少不會說: 這個怎么實現的?還有這種操作?
最后總結一下:
自適應布局需要注意的事:
那么有同學就要問,是不是只要學flex和grid就行了?對不起,所有都要學(就是這么可怕)。各種布局都有他們的使用場景。并且你也攔不住別人用,都需要看懂是吧。只能說要與時俱進,路漫漫其修遠兮,吾將上下而求索。
參考資料
[1] Flex布局教程 - http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
[2] A Complete Guide to Flexbox - https://css-tricks.com/snippets/css/a-guide-to-flexbox/
[3] CSS網格中基于線的定位 - https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid
[4] 網格模板區域 - https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Grid_Layout/Grid_Template_Areas
[5] Why not use tables for layout in HTML? - https://stackoverflow.com/questions/83073/why-not-use-tables-for-layout-in-html
[6] Responsive table layout - http://allthingssmitty.com/2016/10/03/responsive-table-layout/
[7] Using the viewport meta tag to control layout on mobile browsers - https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag
[8] Responsive Web Design - https://www.w3schools.com/css/css_rwd_intro.asp
[9] Can I use - https://caniuse.com/
總結
以上是生活随笔為你收集整理的Web自适应布局你需要知道的所有事儿的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将不确定变为确定~transaction
- 下一篇: java读取utf-8文件第一行多一个问