有這樣一個問題。javascript
通常來講,有如下這些佈局方法:css
float:left|right
display:inline-block
display:flex
display:grid
position:absolute|relative
<table>
或display:table
bootstrap
、Pure.css
等有小夥伴就要說,這也太多了吧,我應該怎麼選擇?html
別急,下面咱們就開始逐一分析各類方法在web自適應佈局下的使用姿式,最後作個總結。java
本文的全部例子使用了同一種三欄佈局。源代碼點我git
float:left|right
最經常使用的佈局方式之一,設置了float
的元素脫離了文檔流。須要注意在使用過浮動後,須要清除浮動,從而避免影響後面的非浮動元素。github
HTMLweb
<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,中間是三欄式佈局。chrome
關鍵cssbootstrap
.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的查詢條件知足時,應用{}
中的樣式。
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%。
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同樣,不重複貼了。
二者都是很經常使用的佈局方式。
若是須要垂直居中,使用inline-block。
inline-block有空白字符壓縮的問題。
使用float,注意要清除浮動。
沒有特別推薦用哪一種,看我的習慣。
好比我在小尺寸的時候,想把content放最上面,left和right都擠下去,怎麼作呢?
float和inline-block佈局沒有純css的方法,要用js把dom扣出來,日後面放,flexbox和grid佈局均可以很好地解決這個問題。
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佈局說白了就是點菜。先想好要吃什麼,而後點必選菜,最後點可選菜,愛點不點。
先想要吃什麼,仍是用以前的例子。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;
,其餘同樣。
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基礎。
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%;
}
}
複製代碼
第二種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;
}
}
複製代碼
詳細教程點這裏: 網格中基於線的定位[3] 和這裏 網格模板區域[4]
position:absolute|relative
至關經常使用,特別是各類特效裏都會用到。
對於自適應佈局,就本身算top
和left
吧。
<table>
或display:table
我的認爲表格佈局比較適用於表格(看上去是廢話,但並非)。
若是是通常的頁面佈局,就不要用table了。Why not use tables for layout in HTML?[5]
關於表格的自適應,看這裏:Responsive table layout[6]
bootstrap
、Pure.css
等所謂萬變不離其宗,用框架佈局也是使用了上面所說的原理,這邊就再也不細說各類框架。
推薦給全部元素加上border-box;
。
* {
box-sizing: border-box;
}
複製代碼
IE盒模型的寬度和高度包括了padding和border,這樣對於百分比的佈局比較好控制,不會出現加起來超過100%而換行的狀況。
在自適應的佈局中少用或者不用固定的高度、寬度,使用百分比, auto或calc()。
<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/