$
標識原生DOM
元素let $white = document.querySelector('.white')
要先將該元素設置position
屬性,absolute
或者relative
等javascript
三類基礎選擇器:css
ID
選擇器;class
選擇器;tag
;如下爲延伸的選擇器:html
.container div{ }
這裏選擇的是class = "container"
的HTML
元素內的全部div
元素,可是不包括container
這個元素;vue
.container > div{ }
選擇的是container
裏面第一層的全部div
:java
.container + div{ }
選擇的是與container
位於同一層的緊挨着的下一個div
:git
注意了,container
同一層緊挨着的下一個元素若是不是div
,那麼該選擇器就選擇不到任何元素:
瀏覽器
.container ~ div{ }
選擇的是與container
處於同一層級下的全部div
:app
即便同一層下的div
元素中有其餘元素隔開,也不影響;框架
*{ }
選擇的是全部的HTML
元素;dom
能夠與其餘選擇器配合使用,好比:
.container ~ *{ }
表示選取與container
同一層下的全部元素;
<a href="https://www.apple.com" title="Apple">Apple</a> <a href="https://www.google.com">Google</a> <a href="https://www.facebook.com">Facebook</a> //1.假如上面有三個超連接,給Apple添加一個title屬性,那麼就能夠經過該屬性選取它 a[title]{ //這樣能夠匹配到全部有title屬性的a標籤 } //2.還能夠經過屬性值進行匹配 a[href="https://www.apple.com"]{ //能夠選擇到href爲蘋果官網的a連接 } //這相似於匹配 a[href^="https"]{ //選擇href屬性值中以https爲開頭的a標籤 } a[href$="com"]{ //選擇href屬性值中以com爲結尾的a標籤 } a[href*="book"]{ //*號會將屬性值book做爲關鍵詞匹配,即選擇href屬性值中有book字符的a標籤 }
a:visited //瀏覽過該a連接後的狀態 a:hover //鼠標移上a標籤後的狀態 .container div:nth-child(3n+0/n/even) //選擇container下的特定一組div元素;
注意:
.card-container:hover .cover{ transform:rotateY(180deg) } //這種狀況表示,當懸停在card-container標籤上時,改變.cover的樣式;而不是僅僅侷限於選擇card-container這個標籤
要選擇.back
和.cover
兩個標籤不能這樣寫呀:.cover .back
,要這樣寫.cover, .back;
中間要用逗號隔開;
.cover, .back{ width: 100%; height: 100%; position: absolute; backface-visibility: hidden; //這裏寫transition表示以後對.cover和.back標籤樣式所作的修改(如hover)添加一個過渡過程 transition: transform .25s ease-in-out; }
絕對單位,1px
表明一個像素點,一般修改段落中文字大小時,除了修改font-size
,還要修改line-height
;
相對大小;1em=多少px
,是基於目前這個容器中的font-size
大小設定的,取決於使用em
單位的標籤的父標籤(直系),的font-size
;以下圖所示:
上圖中,每一層div
中的1em
值,都取決於上一層div
中的font-size
值;
在用em
單位設置文字段落的字體大小時,只須要修改父元素的font-size
,那麼使用em
單位的font-size
和line-height
就不須要更改了,會自動等比例縮放;
也就是root em
。它與em
類似,惟一的不一樣是它是基於html
元素的font-size
大小來計算的,不受上一級的父標籤影響;
好比上面第一個例子,將em
改成rem
,則不一樣層(框)內的字體大小不會受到父元素的影響:
優點爲,更容易計算,只須要更改html
標籤中的font-size
便可統一修改全部rem
單位。能夠避免元素被多層嵌套後難以預測它的實際大小。
全寫爲viewport width
和viewport height
;它們的取值範圍爲:1~100
;
當width:100vw
;height:100vh
時,該元素會佔滿整個屏幕,當將父元素這樣設置後,就可以很好地將子元素進行居中處理;
vmin
表明屏幕較短的一邊,vmax
表明屏幕較長的一邊,取值也是1~100
;在移動端實現屏幕旋轉顯示。好比:一張正方形的圖片:
<img src="demo.jpg"> img{ width:100vmin; //width:100vmax; }
當寬設爲100vmin
時,就會以屏幕較短的一邊的總長度做爲圖片的邊長,即便旋轉屏幕後,邊長也不會改變;
當寬設爲100vmax
時,就會以屏幕較長的一邊的總長度做爲圖片的邊長,旋轉屏幕後,邊長也不會改變,不能顯示的區域將會出現滾動軸;
其餘的佈局如table
,float
等都不是設計來作網頁佈局的,而Flexbox
是第一套專門爲了網頁佈局而設計的方法。
flex
佈局的預設值爲block
,因此一開始設置了flex
佈局(display:flex
)的元素都會獨佔一行。
Flex
佈局主要能夠分爲兩部分:flex-container
(整個彈性盒容器)和flex-items
(彈性盒中的元素);
flex
全屬性實時預覽:http://flexbox.help/
這些屬性寫在設定爲flex-container
的標籤中;經過給標籤添加:display:flex
;可使該標籤成爲一個flex-container
。
設置flex-container
內的items
的排序方向,默認值爲row
(行/水平排序),其餘屬性值有:
column
:列/豎直排序;row-reverse
:反向水平排序;column-reverse
:反向豎直排序;不一樣的排序方向,主軸與交叉軸不同:
決定主軸的排序方向;有如下屬性值:
center
:主軸上居中;flex-start
:主軸起始方向開始排列(默認表示左);flex-end
:主軸結束方向開始排列(默認表示右);space-around
:空白環繞;space-between
:與around
類似,只不過沒有了最左和最右的空白;space-evenly
:空白平分;決定交叉軸的排序方向;有如下屬性值:
center
:交叉軸上居中;flex-start
:交叉軸起始方向開始排列(當flex-direction
爲默認值row
時,表示上);flex-end
:交叉軸結束方向開始排列;(默認表示下)space-around
:空白環繞;space-between
:與around
類似,只不過沒有了最左和最右的空白;space-evenly
:空白平分;justify-content:center
與align-item:center
配合使用可使flex-container
(彈性盒)內的items
水平和垂直方向上居中。
當彈性盒內的item
過多時,該屬性能夠控制,是壓縮每一個item
寬度不換行,仍是保持每一個item
寬度換行;
nowrap:壓縮
item`寬度,不換行;
wrap
:不改變item
寬度,換行;(換行後,會將彈性盒一分爲二,因此兩行item
並非挨在一塊兒的)
該屬性爲flex-direction
和flex-wrap
組合的縮寫;如:
flex-flow:row wrap;
等效於flex-direction:row;flex-wrap:wrap;
這個屬性的前提條件爲flex-wrap
爲wrap
時,即有多行flex items
時纔會生效;用於設定多行flex-items
間行與行間的對齊方式,屬性值有:
flex-start
:在交叉軸開始方向上排列:
flex-end
:交叉軸結束方向上排列:
center
:交叉軸中間:
initial
:默認值,保持原來的樣子:
space-around
:與上面同樣:
space-between
:(上下)平均分空白,與around
類似,不過消除了最左和最右的空白:
space-evenly
:平分空白區域:
用於調整flex item
(盒內元素)的排序順序,根據order
的值按照主軸方向由小到大排序,默認值爲0
;好比C
的order
設置爲1
,由於它最大,因此C
排到最後:
該屬性用於複寫flex container
的align-items
屬性;也就是說align-items
是對於全體的flex items
作出規劃,而align-self
則是設置個別flex items
的排序方向:
如上圖所示,因爲align-items:center;
因此總體的flex items
是居中的,可是,設置了align-self
的C
和D
會按照align-self
的值進行從新排列;
該屬性用於設定flex-item
在主軸方向上的大小;好比,當主軸爲row
時,能夠經過設定該屬性的值來修改每個flex-item
的寬,這樣flex-item
原來的寬就失效了。
同理,當flex-direction:column;
即主軸爲豎直方向時,flex-basis
設定的屬性值將是每個flex-item
的高;
若是設置爲0
的話,至關於將width/height
設置爲0
,這樣每一個flex-item
在沒有設置overflow:hidden;
的狀況下,大小都由內容撐開;
設定爲auto
時,則按照原來設定的寬度來計算:
也就是圖中的60px
。
該屬性是指在flex-container
主軸方向上有剩餘空間的時候,flex item
沿主軸方向擴大的設定。
好比,原來的佈局以下圖所示:
將flex-grow:1;
時:
可見flex-item
自動平分了主軸的空白空間。1
的意思是每個flex-item
都佔有主軸空白空間的一份,也就是1/3
。
設定A
的flex-grow:0;
則A
保持原樣,不擴大;將B
的flex-grow:4;
表示先將空白區域分爲(4+1+0=6
份)而B
佔其中的4
份,C
佔1
份也就是:
與flex-grow
效果相反,即當flex-item
超過了主軸長度,沿主軸方向怎樣縮小的設定。默認值爲1
,即爲了避免使flex-item
突出整個flex-box
會自動縮小每一個flex-item
。
如圖:當設定每一個flex-item
的flex-shrink:0;
時即保持每一個flex-item
原來的大小,此時會超出主軸90px
:
若是這樣設定:
.A{flex-shrink: 1} .B{flex-shrink: 1} .C{flex-shrink: 1}
即三個flex-item
平分突出的部分,即A
、B
、C
各縮小30px
:
若是這樣設定:
.A{flex-shrink: 1}//share 1/5 .B{flex-shrink: 3}//share 3/5 .C{flex-shrink: 1}//share 1/5
則B
承擔3/5
的突出部分,也就是要縮小90x3/5=54px
,其他兩個flex-item
只須要縮小1/5
,也就是18px
:
這個屬性爲flex-grow
,flex-shrink
和flex-basis
組合起來的縮寫;
當這樣設定時:
flex:1 1 auto; //至關於 flex-grow: 1; flex-shrink: 1; flex-basis: auto;
也就是說flex-item
會按照flex-container
(彈性盒)的主軸長度平均分配空間去放大或縮小。
當flex-container
有空白空間的時候,同步擴大:
當flex-container
沒有空白空間時的時候,同步縮小:
再如:
flex: 0 1 150px
此時,flex-grow:0;
即有空白空間時保持原樣,不擴大;總體來說就是隻有在flex-container
空間不足時同步縮小,而且固定每一個flex-item
在主軸上的長度爲150px
。
再如:
flex:0 0 200px
即固定每一個flex-item
主軸方向上的長度爲200px
,不管flex-container
有無空白空間都不擴大或縮小:
當 flex
取值爲 none
,則計算值爲 0 0 auto
,以下是等同的:
.item {flex: none;} .item { flex-grow: 0; flex-shrink: 0; flex-basis: auto; }
當 flex
取值爲 auto
,則計算值爲 1 1 auto
,以下是等同的:
.item {flex: auto;} .item { flex-grow: 1; flex-shrink: 1; flex-basis: auto; }
這就是flex:1的真面目
當 flex
取值爲一個非負數字,則該數字爲 flex-grow
值,flex-shrink
取 1
,flex-basis
取 0%
,以下是等同的:
.item {flex: 1;} .item { flex-grow: 1; flex-shrink: 1; flex-basis: 0%; }
當 flex
取值爲一個長度或百分比,則視爲 flex-basis
值,flex-grow
取 1
,flex-shrink
取 1
,有以下等同狀況(注意 0%
是一個百分比而不是一個非負數字):
.item-1 {flex: 0%;} .item-1 { flex-grow: 1; flex-shrink: 1; flex-basis: 0%; } .item-2 {flex: 24px;} .item-1 { flex-grow: 1; flex-shrink: 1; flex-basis: 24px; }
當 flex
取值爲兩個非負數字,則分別視爲 flex-grow
和 flex-shrink
的值,flex-basis
取 0%
,以下是等同的:
.item {flex: 2 3;} .item { flex-grow: 2; flex-shrink: 3; flex-basis: 0%; }
當 flex
取值爲一個非負數字和一個長度或百分比,則分別視爲 flex-grow
和 flex-basis
的值,flex-shrink
取 1
,以下是等同的:
.item {flex: 2333 3222px;} .item { flex-grow: 2333; flex-shrink: 1; flex-basis: 3222px; }
flex
的默認值是以上三個屬性值的組合。假設以上三個屬性一樣取默認值,則 flex
的默認值是 0 1 auto
。同理,以下是等同的:
.item {flex: 2333 3222 234px;} .item { flex-grow: 2333; flex-shrink: 3222; flex-basis: 234px; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; } ul{ list-style: none; /* 此時ul成爲了flex-container */ display: flex; justify-content: space-around; background-color: #eee; padding: 8px 0; } ul > li a{ display: block; padding: 4px 8px; } </style> <style> </style> </head> <body> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Products</a></li> <li><a href="#">Protfolio</a></li> <li><a href="#">Contact</a></li> </ul> </body> </html>
效果圖:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .post .thumbnail img{ display: block; width: 100%; height: auto; border-radius: 100%; } .post .thumbnail{ flex: 0 1 350px; min-width: 200px; } .post{ display: flex; flex-direction: row; padding: 2em; border-bottom: 1px solid #eee; } .content{ display: flex; flex-direction: column; margin-left: 1.2em; flex: 1 1 auto; } .content h4{ font-weight: bold; } .content .excerpt{ font-size: .8em; color: #666; } </style> </head> <body> <div class="post"> <div class="thumbnail"> <img src="http://ahuntsun.gitee.io/blogimagebed/img/vuepress/home/1.jpg" alt=""> </div> <div class="content"> <h4 class="title"> Flexbox Example</h4> <div class="excerpt"> The economic downturn in the US triggered by the pandemic has been officially declared a recession.Meanwhile, US markets continued their rebound on Monday, as investors remained optimistic that the downturn will be short-lived. </div> </div> </div> </body> </html>
效果圖:
佈局方式大體有四種:Table
、Float
、Flexbox
、Grid
;
Table
佈局是最古老的佈局,如今已不多使用。Float
曾經盛行一時,被稱爲「DIV + CSS
佈局」;而Flexbox
和Grid
纔是真正爲了網頁佈局而設計的;
Flexbox
屬於一維(1-Dimension
)的排版方式,而Grid
則是二維(2-Dimensions
)的排版方式。也就是說一個Flexbox
容器只能控制一個方向,即水平方向或者垂直方向,若是要控制另外一方向則須要再添加一層Flexbox
容器;Grid
容器則能夠一次過控制兩個方向,這樣就能夠直接定義容器中元素的位置了。
經過如下代碼,設置一下佈局,經過一張帶標尺的背景圖片能夠更直觀地對比:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Grid</title> <style> #grid-container{ /* 將父容器(div)設置爲grid佈局 */ display: grid; width: 500px; height: 500px; background-color: #eee; /* 將整個grid-container分割成5x5的方格,每格100 x 100 */ /* 該屬性將grid-container分割爲五行,每行高100px */ grid-template-rows: 100px 100px 100px 100px 100px; /* 該屬性將grid-container分割爲五列,每列寬100px */ grid-template-columns: 100px 100px 100px 100px 100px; } body{ margin: 40px; } #ruler{ position: absolute; top: 0; left: 0; width: 580px; height: 580px; background-image: url('https://codingstartup.com/assets/grid/grid-ruler.png'); background-size: 580px 580px; } .cell-1{ background-color: blue; } .cell-2{ background-color: yellow; } </style> </head> <body> <div id="ruler"></div> <div id="grid-container"> <div class="cell-1"></div> <div class="cell-2"></div> </div> </body> </html>
能夠看到預設狀況下grid-container
中的元素是這樣排列的;
若是咱們想讓藍色的cell-1
佔據左上方的四格的話,從圖中可看出,目標範圍爲row
方向的1~3
;column
方向的1-3
;能夠這樣設置樣式:
.cell-1{ background-color: blue; grid-row: 1 / 3; grid-column: 1 / 3; }
效果爲:
若是想讓黃色的cell-2
佔據row
方向的4-6
,column
方向的1-3
,則須要這樣設置:
.cell-2{ background-color: yellow; grid-row: 4 / 6; grid-column: 1 / 3; }
效果爲:
該屬性爲grid-row
和grid-column
的簡寫,以黃色的cell-2
爲例:
.cell-2{ background-color: yellow; grid-row: 4 / 6; grid-column: 1 / 3; //等同於 //grid-area: 4 / 1 / 6 / 3; }
能夠看到,grid-area
的值至關於元素的左上角和右下角的,以(ROW, COLUMN)爲形式的座標。即左上角:(4,1)、右下角:(6,3)。
實際開發時並無一把尺來參考,以藍色方塊爲例,能夠採起下列寫法:
.cell-1{ background-color: yellow; grid-row: 1 / 4; grid-column: 2 / span 3; }
意思爲ROW
方向從1~4
,COLUMN
方向上從2
開始,span 3
表示從2開始往COLUMN
方向延伸3格,效果以下:
如上圖所示,grid-container
中水平和垂直方向上各有6
條線,將整個grid-container
空間分割成了25
份;這些線在CSS Grid
中被稱爲Grid Line
。這些Grid Line
是能夠命名的。首先給ruler
換一個背景:
#ruler{ position: absolute; top: 0; left: 0; width: 580px; height: 580px; background-image: url('https://codingstartup.com/assets/grid/grid-ruler-xy.png'); background-size: 580px 580px; }
效果爲:
也就是將水平方向的Grid Line
命名爲X1~X6
;垂直方向的Grid Line
命名爲Y1~Y6
;
能夠在grid-container
中這樣設置:
#grid-container{ grid-template-rows: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px [Y6]; grid-template-columns: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px [X6]; }
設置好Grid Line
名字後,就能夠這樣來設置了,以藍色的cell-1
爲例:
.cell-1{ grid-row: Y1 / Y4; grid-column: X2 / X6; }
上面的代碼表示,ROW
方向範圍爲Y1~Y4
之間,COLUMN
方向範圍爲X2-X6
之間。
效果爲:
grid-container
中的線被稱爲grid line
,而方格則稱爲Grid Area
;咱們也能夠直接給特定的格子命名;
在grid-container
中添加多兩個格子cell-3
和cell-4
,分別爲橙色和黑色;重置cell-1
,cell-2
的佈局,將ruler
換回原來的背景:
//html結果 <div id="grid-container"> <div class="cell-1"></div> <div class="cell-2"></div> <div class="cell-3"></div> <div class="cell-4"></div> </div> //css樣式 .cell-1{ background-color: blue; } .cell-2{ background-color: yellow; } .cell-3{ background-color: orange; } .cell-4{ background-color: black; }
隨後咱們能夠在grid-container
中添加grid-template-ares
屬性,該屬性的值與grid-container
中的每個格子一一對應:
#grid-container{ grid-template-areas: "header header header header header" "nav main main main main" "nav main main main main" "nav main main main main" ". footer footer footer ."; }
上面的點表示不給左下角和右下角的格子命名。此時就定義了四個grid-area
分別是:header
、nav
、main
和footer
;
使用方法也很簡單,以藍色的cell-1
爲例,在該格子中添加grid-area
屬性,值設置爲header
:
.cell-1{ background-color: blue; grid-area: header; }
那麼cell-1
就佔據了grid-area
中名字爲header
的區域,也就是第一行:
隨後再分別將cell-2
的grid-area
設置爲nav
、cell-3
設置爲main
、cell-4
設值爲footer
:
.cell-2{ background-color: yellow; grid-area: nav; } .cell-3{ background-color: orange; grid-area: main; } .cell-4{ background-color: black; grid-area: footer; }
效果爲:
這樣全部的元素都定位到設定好的位置上了;
將ruler
中做爲尺的背景圖去掉,就出現了熟悉的佈局了:
還能夠在grid-container
中經過row-gap
設置行距,column-gap
設置列距;好比都設置爲10px
:
#grid-container{ row-gap: 10px; columns: 10px; }
效果爲:
因爲上下左右都多了40px
,隨後將grid-container
的長寬增長40px
就能夠了。
Fr
爲Grid
中的比例單位,表示佔一份的意思。好比:
#grid-container{ grid-template-rows: 300px 100px 100px 100px 100px; grid-template-columns: 100px 100px 100px 100px 100px; } //可改寫爲 #grid-container{ grid-template-rows: 3fr 1fr 1fr 1fr 1fr; grid-template-colmn: 1fr 1fr 1fr 1fr 1fr; }
第二種寫法表示,將grid-container
的row
方向上分爲7
份,第一行佔3
份,其他四行各佔1
份;在column
方向上分紅5
份,五列每列佔一份。
還能夠經過repeat
函數簡寫,該函數第一個參數表示重複幾回,第二個參數表示重複什麼,可是該函數不適用於grid-template-areas
。以上設置可改寫爲
#grid-container{ grid-template-rows: 3fr repeat(4, 1fr); grid-template-colmn: repeat(5, 1fr); }
將父元素(容器)設定text-align:center
,就能夠左右置中了;
將元素自己的margin-left
與margin-right
設置爲auto
,也就是一般的:margin: 0, auto;
就能夠左右居中了;
#block{ position:absolute;//使元素浮動,脫離文檔流 top: 50%; left: 50%;//這樣設置了top和left後,block的左上角就對齊了畫面的中心點 //要將block的中心點與畫面的中心點重合,須要將block向上和左偏移block尺寸的一半,能夠採用transform transform:translateX(-50%) translateY(-50%); } //一樣能夠採用下列寫法 #block{ position: absolute; bottom: 50%; right: 50%; transform: translate(50%, 50%); }
能夠這樣設置,使body
的內容,上下左右居中:
body{ min-height: 100vh; display: flex; //將body設置爲flex-container justify-content: center; //將主軸上的flex-item居中 align-items: center; //將交叉軸上的flex-item居中 }
原理爲將父元素設置爲表格佈局(display:table
),裏面要居中的元素設置爲表格的一個格子(display: table-cell
),這樣vertical-align
屬性就能對這個格子生效了;這樣設置:
<body> <div class="cell"></div> </body> body{ display: table; width: 100%; min-height: 100vh; } .cell{ display: tabel-cell;//此時.cell就會成爲表格的一個儲存格 vertical-align: middle;//此時vertical-align屬性就生效了,達到上下居中 text-align: center; //設置左右置中 }
總結:以上三種方法中:
Position:absolute
;對齊的是元素自己,只須要調整須要居中的元素自己便可;Flexbox
)和第三種(Table
)方法,對齊的是元素內容。都須要先將父容器調整成與畫面相同的大小(這就是min-height: 100vh;
的做用),而後再設定它的內容(子元素)的對齊方式。position
有五個設定值,分別是:static
、absolute
、relative
、fixed
和sticky
。
HTML
裏面全部元素的Position
默認值都是static
,設定了該屬性的元素,不會脫離文檔流,會隨着HTML
文檔排版的流程(flow
)而發生變化。
首先,搭建如下的HTML
和CSS
樣式:
效果爲:
爲了方便說明,事先爲
static
類添加了樣式(下同);
隨後在html
樣式中新增一句"Hello World"
:
Hello World <div class="static"></div>
能夠看到這個static
的div
就會由於這一行文字而向下移動了一點:
再次改寫HTML
和CSS
樣式:
//HTML結構 <div class="height"></div> <div class="static"></div> //CSS結構 .static{ position: static; width: 360px; height: 360px; } .height{ width: 750px; height:120px; }
效果以下:
能夠看到,height
div高爲120px
,因此static
的div就要相應下移120px
;
注意:position
值爲static
的元素對於top
、left
、right
、bottom
的設定值都是不會生效的;
以下改寫HTML
和CSS
結構:
//HTML結構 <div class="height"></div> <div class="absolute"></div> //CSS結構 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
效果爲:
如圖所示,right
的設定值是將元素定位到與HTML
文檔右邊相距80px
的位置;bottom
則是將元素定位到與HTML
文檔底部相距60px
的位置。
absolute
元素會固定在所設定的位置,不會隨着HTML文檔排版的流程移動,即脫離文檔流。
更改樣式,加多幾個高度爲120px
的藍色height
div:
//HTML結構 <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="absolute"></div> //CSS結構 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
效果:
能夠看到並無影響到absolute
元素所在的位置的。可是若是absolute
元素所在的容器有滾動軸的話,它就會隨着滾動軸移動:
再次更改樣式,添加多一個absolute
div:
//HTML結構 <div class="height"></div> <div class="absolute"></div> <div class="absolute"></div> //CSS結構 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
乍一看頁面沒有發生變化:
可是,實際上兩個absolute
元素是重疊到一塊兒了。能夠經過將其中一個absolute
元素的right
設定爲100px
,證實:
<div class="absolute" style="right: 100px"></div>
能夠看到這兩個absolute
元素確實是重疊在一塊兒的:
再次更改樣式,將absolute
元素放在absolute
元素內,結果會如何呢?
//HTML結構 <div class="height"></div> <div class="absolute"> <div class="absolute"></div> </div> //CSS結構 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
結果是裏面的absolute
元素的right
與bottom
是根據外面那層的absolute
元素的位置去定位的。因此會再向左偏移80px
,向上多偏移60px
:
新增一個relative
div並改寫樣式:
//HTML結構 <div class="height"></div> <div class="relative"></div> //CSS結構 .height{ width: 750px; height:120px; } .relative{ position: relative; width: 360px; height: 360px; top: 60px; left: 150px; }
效果如圖所示:
可見,relative
與static
是很類似的,都是會跟隨HTML
的排版流程(文檔流)移動。可是它比Static
多了top
、left
、right
、bottom
的設定。也就是說,它在跟隨HTML
排版流程去定位之餘,還能夠經過這四個值進一步調整位置。
好比在上面增長一個height
div:
//HTML結構 <div class="height"></div> <div class="height"></div> <div class="relative"></div>
relative
元素就會因上方增長的內容而向下移動:
除此以外,relative
最重要的一個功能是:在它裏面的absolute
元素會根據relative
的位置去定位;好比在它裏面加一個absolute
div:
//HTML結構 <div class="height"></div> <div class="height"></div> <div class="relative"> <div class="absolute"></div> </div>
會發現absolute
元素的right
與bottom
是根據relative
元素的位置去定位的:
有人可能會認爲這不是很正常嘛,咱們將relative
改爲static
:
//HTML結構 <div class="height"></div> <div class="height"></div> <div class="static"> <div class="absolute"></div> </div>
能夠看到,absolute
元素會直接無視包含它的static
元素:
總結:relative
相對於static
,主要增長了兩大功能:
第一:relative
具有了top
、left
、right
、bottom
的設定;
第二:可使absolute
子元素根據它的位置去定位,也就是子絕父相;
新增一個fixed
div:
//HTML結構 <div class="height"></div> <div class="height"></div> <div class="fixed"></div> //CSS結構 .height{ width: 750px; height:120px; } .fixed{ position: fixed; width: 240px; height: 240px; bottom: 60px; left: 80px; }
效果爲:
fixed
與absolute
是很類似的,不一樣的地方有兩點:
第一:fixed
會固定到熒幕中的固定位置,即便滾動頁面,它的位置也不會發生改變;
增添多個height
div,能夠發現即便滾動頁面,fixed
div位置也不變:
第二:若是fixed
div設定了top
、left
、bottom
、right
的值,即便將它放入relative
div中,fixed
div 依舊會根據頁面,也就是body
去定位,而不會根據relative
div去定位。
改寫樣式,在relative
div 中添加一個fixed
div:
//HTML結構 <div class="height"></div> <div class="relative"> <div class="fixed" style="position: fixed; width: 50px; height: 50px; background-color: #000"></div> </div>
在fixed
div不添加top
、left
、bottom
、right
屬性時,fixed
div 會相對於包裹它的relative
div 定位:
當設定了top
、left
、right
、bottom
其中一些屬性以後:
//HTML結構 <div class="height"></div> <div class="relative"> <div class="fixed" style="position: fixed; width: 50px; height: 50px; background-color: #000; top: 50px"></div> </div>
fixed
div 就會脫離包裹它的relative
div 的束縛,而根據body
進行定位:
添加sticky
div 改寫樣式:
//HTML結構 <div class="height"></div> <div class="sticky"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> //CSS結構 .height{ width: 750px; height:120px; } .sticky{ position: sticky; width: 240px; height: 90px; top: 0; }
能夠看到,頁面出現了滾動軸:
隨後滾動頁面:
能夠發現,sticky
div 在滾動的過程當中,當貼到頁面頂部的時候,就會固定在頁面頂部,也就是"粘住了";之因此會粘住是由於咱們設置了sticky
div 的top
爲0
,當它距離頁面頂部0px
的時候,就會觸發top:0px;
這一屬性。
HTML
元素大體上默認分爲兩種形態,一種爲Block
,另外一種爲Inline
。Block
爲區塊的意思,Inline
爲內聯的意思。
Block
元素會獨佔一行,好比兩個段落,即便源碼中沒有空格,顯示的兩段文字也會隔開(由於p
標籤是塊元素):
因爲塊元素是獨佔一行的,因此,即便一行中有空間也不容許兩個塊元素左右排列,以下圖所示將p
標籤的寬度設置爲50%
後,兩個P
標籤也不會左右排列。
HTML
源碼中會將多個空格合併爲一個空格進行顯示,若要加多個空格能夠添加: (no-break-space)
Block
元素的特色爲:
Block
元素之間只能上下排列;width
和height
設定;常見默認爲Block
的標籤有:div
、p
、h1
到h6
、ul
等。
以下圖所示,在p
標籤中加入 strong
標籤,並設置樣式:
這裏的 strong
就是inline
內聯元素。它的特色爲:
Inline
標籤之間能夠左右排列;inline
元素的大小由所包含的內容決定,不受width
和height
影響;常見默認爲inline
的標籤有 a
、 strong
、 span
等。
它結合了Inline
和Block
二者的特性,既能夠設定寬度和高度,又能夠與其餘Inline
元素並排。
好比在段落的最後面加一個超連接按鈕,就能夠採用Inline-Block
:
樣式爲:
//HTML <p> //some words <a href="#">More...</a> </p> //CSS a{ display: inline-block; width: 80px; height: 40px; line-height: 40px; text-align: center; background-color: black; color: white; border-radius: 4px; text-decoration: none; }
效果以下,這樣就能夠賦予自己爲內聯標籤的a
標籤以塊級標籤特性了:
全部HTML
元素均可以經過更改display
屬性將它設置爲Blcok
、Inline
、Inline-Block
;
改寫以下樣式:
//HTML <div>Block</div> <span>Inline</span> <br> <strong>Inline-block</strong> //CSS div{ width: 50%; } span{ } strong{ display: inline-block; } div, span, strong{ background-color: black; color: white; }
效果以下:
隨後給body添加樣式:
body{ text-align: center }
能夠看到Inline
與Inline-Blick
元素都水平居中了,而block
元素只是將裏面的文字居中了,block
元素自己並無居中:
這是由於Inline與Inline-Blick兩者的容器的大小都是由內容決定,因此text-align:center
對整個元素都有效;而對Block
元素無效,只對該元素內部的文字有效。要想讓block
元素和其中內容都居中,須要設置block
元素的margin
樣式:
div{ width: 50%; margin-left: auto; margin-right: auto; }
此時就能達到水平居中了:
總結:居中方法:
Inline與Inline-Blick:
body{ text-align: center }
Block:
body{ text-align: center } div{ width: 50%; margin-left: auto; margin-right: auto; }
CSS Box Model
一共包括了四種屬性:Content
、Padding
、Border
和Margin
。
它們的結構和排序順序是這樣的:
由內往外分別是:content
、padding
、border
、margin
。
關於margin
與padding
:
在標準盒子模型中,Width = content
;
也就是說只要改變了content
、padding
、border
、margin
中的任一個值,都會撐大整個盒子。
在怪異盒子模型中,Width = content + padding + border + margin
;
一旦設置了元素的width
大小後,至關於固定了整個盒子的大小。再去改變上面的四個屬性,盒子總體的大小不變,四個屬性自動調整。
利用這一特性,就能夠隨便更改盒子的margin
、content
、padding
、border
屬性值而不用擔憂撐大盒子了。
盒子默認爲標準盒子模型,即box-sizing:content-box;
能夠經過:box-sizing:border-box
,來將它設置爲怪異盒子模型。
margin
時:只會左右生效,上下會失效:使用padding
時:上下左右都生效,只不過只有左右隔開了,改變了佈局;上下沒有改變佈局,只是覆蓋了:
能夠這樣記憶,inline
元素的margin
和padding
屬性都不會影響垂直方向上的佈局。
inline-block
元素的margin
和paddind
屬性在上下左右四個方向上都會生效:
上下排列的兩個塊級元素,分別設置margin-bottom
和margin-top
;總體的空隔取兩者的最大值,而不會疊加;解決方法爲:在中間加入一個有高度的元素,好比1px
的border
(一般經過爲元素::after
添加);
先來看看採用瀑布流佈局的典型例子:Pinterest
:世界上最大的圖片社交分享網站。
最簡單實現的方法是使用別人寫好的插件好比:
Masonry.js
lsotope.js
它們實現的原理是經過javascript
計算一共有多少個方格,在計算每個方格的寬度和高度,因容器的寬度能夠放置多少列等等要求。將所有方格的position
都設置爲absolute
,逐一計算它們的top
和left
實現定位。
因爲全部方格的位置是計算出來的,當頁面寬度變化時能夠實現動態地從新排列。
下面介紹使用純CSS
實現瀑布流的兩種方法,並分析它們的限制:
方法一:僅適用column-count
和column-gap
兩個屬性實現
代碼爲:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Column 實現瀑布流佈局</title> <style> body{ margin: 4px; font-family: Helvetical; } .masonry{ column-count: 4; column-gap: 0; } .item{ padding: 2px; position: relative; /*給每張圖片加上編號*/ counter-increment: item-counter; } .item img{ display: block; width: 100%; height: auto; } /*給每張圖片加上編號*/ .item::after{ position: absolute; display: block; top: 2px; left: 2px; width: 24px; height: 24px; text-align: center; line-height: 24px; background-color: #000; color: white; content:counter(item-counter) } </style> </head> <body> <!-- 方法一:僅適用column-count和column-gap兩個屬性實現 --> <div class="masonry"> <!-- 經過picsum獲取隨機圖片,並隨機設置一下每張圖片的尺寸 --> <div class="item"> <img src="https://picsum.photos/360/460?random=1" alt=""> </div> <div class="item"> <img src="https://picsum.photos/320/260?random=2" alt=""> </div> <div class="item"> <img src="https://picsum.photos/100/160?random=3" alt=""> </div> <div class="item"> <img src="https://picsum.photos/310/400?random=4" alt=""> </div> <div class="item"> <img src="https://picsum.photos/260/360?random=5" alt=""> </div> <div class="item"> <img src="https://picsum.photos/370/480?random=6" alt=""> </div> <div class="item"> <img src="https://picsum.photos/320/260?random=7" alt=""> </div> <div class="item"> <img src="https://picsum.photos/330/440?random=8" alt=""> </div> <div class="item"> <img src="https://picsum.photos/150/220?random=9" alt=""> </div> <div class="item"> <img src="https://picsum.photos/230/230?random=10" alt=""> </div> </div> </body> </html>
效果爲:
優勢:代碼簡單,只須要使用column-count
和column-gap
兩個屬性便可;
缺點:圖片的排列順序是從第一列的上到下,再到下一行的上到下;
沿用第一種方法的HTML
結構,更改樣式以下:
body{ margin: 4px; font-family: Helvetical; } .masonry{ /* 這樣設置後,圖片組成的flex-item高度超過1000px就會換一列,向右排列 */ display: flex; flex-direction: column; flex-wrap: wrap; height: 1000px; } .item{ position: relative; width: 20%; padding: 2px; box-sizing: border-box; /* 爲每一個item加上編號 */ counter-increment: item-counter; } .item img{ display: block; width: 100%; height: auto; } /* 爲每一個item加上編號 */ .item::after{ position: absolute; display: block; top: 2px; left: 2px; width: 24px; height: 24px; text-align: center; line-height: 24px; background-color: #000; color: white; content:counter(item-counter) }
此時效果與第一種方法一致:
不過,能夠經過flex
佈局中的order
屬性,更改它的排序順序。添加以下樣式:
body{ margin: 4px; font-family: Helvetical; } .masonry{ /* 這樣設置後,圖片組成的flex-item高度超過1000px就會換一列,向右排列 */ display: flex; flex-direction: column; flex-wrap: wrap; height: 1000px; } .item{ position: relative; width: 25%; padding: 2px; box-sizing: border-box; /* 爲每一個item加上編號 */ counter-increment: item-counter; } .item img{ display: block; width: 100%; height: auto; } /* 爲每一個item加上編號 */ .item::after{ position: absolute; display: block; top: 2px; left: 2px; width: 24px; height: 24px; text-align: center; line-height: 24px; background-color: #000; color: white; content:counter(item-counter) } /* 選取第一行的item,當n=0~3時,能夠選取到一、五、九、13 */ .item:nth-child(4n+1){ order: 1; } /* 選取第二行的item,當n=0~3時,能夠選取到二、六、十、14 */ .item:nth-child(4n+2){ order: 2; } /* 選取第三行的item,當n=0~3時,能夠選取到三、七、十一、15 */ .item:nth-child(4n+3){ order: 3; } /* 選取第四行的item,當n=0~3時,能夠選取到四、八、十二、16 */ .item:nth-child(4n){ order: 4; }
效果爲:
這種方法主要使用了Flex
中的order
屬性;
存在的問題:須要設置Flex
容器的高度。因此咱們須要知道內容加起來的高度是多少。還要考慮要分爲多少個豎行。去爲Flex
容器計算一個合理的高度。好比改變頁面的寬度,會出現只須要三個豎行就能容納圖片的狀況:
而這種狀況咱們是不但願看到的;
綜上所述:要實現瀑布流簡單時可使用column,完美實現時還需採用js套件。
元老級的佈局屬性,幾乎不存在兼容性問題,連IE6
也支持。
Float
最初是爲了解決"繞圖排文"問題設計的。不使用Float
時:
<img src="https://picsum.photos/200/200"/> <p>一段文字</p>
效果爲:
爲加上
float
屬性就能夠實現"繞圖排文"了:
img{ float:left;// 脫離文檔流 display: block;// join文檔流 margin-right:20px; }
設置樣式:
//HTML <div class="container"> <div class="left">一段文字</div> <div class="middle">一段文字</div> <div class="right">一段文字</div> </div> <p> 一段文字 </p> //CSS .left .middle .right{ background-color:yellow; } .right{ float:left; width:33.3%; } .left{ float:left; width:33.3%; } .right{ float:left; width:33.3%; }
此時的效果爲(大體):
三個浮動的div
並無由於被container
div 包裹着而與p
標籤隔開,這是由於,三個div
都浮動起來了,與container
div 不在一個平面上。就好像橡膠圈同樣container
捆不住這些浮動的div
,因此會出現這樣的狀況,即container
div 出現了元素坍塌;
爲了恢復正常就須要清除父容器container
div 中子元素的浮動了,有如下三種方法:
第一:clearfix
這個類的做用爲結束float
繼續影響後續內容的排版;使用方法爲在父容器container
div 同一層加上一個塊級元素,再添加以下的樣式:
//HTML <div class="container"> </div> <div class="clearfix"></div> //CSS .clearfix{ clear:both; }
如今,排版就正確了:
這種方式並不優雅,不經過添加HTML
塊級標籤,而是經過僞類after
的方式添加,樣式以下:
//HTML <div class="container"> </div> //CSS .container::after{ content: ''; clear:both; display:block; }
第二:overflow
只須要將父容器container
div 的overflow
屬性設置爲visible
之外的任何一個值,好比auto
或hidden
。
//HTML <div class="container"> </div> //CSS .container{ overflow:auto; }
此時這個container
div 就會變成一個BFC
(Block Formatting Context
:塊級可視化上下文),BFC
會造成一個局部的塊級,達到"隔斷"的效果。
第三:display
爲父容器container
div 添加display:flow-root;
便可將其變成一個BFC
。
//HTML <div class="container"> </div> //CSS .container{ display: flow-root; }
不過這個屬性較新,而且全部的IE版本都不支持:
響應式佈局指的是網頁會因不一樣設別的屏幕大小,例如電腦、手機、平板等設備。自動調整版面佈局,圖片及字體大小等。使網頁適應在不一樣大小的熒幕下顯示。
分別有如下幾個方面:
能夠經過設置Media Query
的Breakpoint
(斷點),而且設置當符合這個Breakpoint
的時候,改變CSS
樣式。
例如:
@media screen and (max-width: 360px){ }
在上面的設定中,screen
指有屏幕的設備;max-width: 360px
表示Query
或是叫Breakpoint
,指屏幕最大寬度爲360px
;經過and
組合起來就是:當設備有屏幕,而且最大寬度爲360px
如下的狀況下,觸發花括號內的CSS
樣式。
還能夠設置屏幕寬度較寬時的樣式:
@media screen and (min-width: 960px){ }
上述設置指的是,屏幕寬度大於960px
的狀況下觸發花括號內的CSS
。
至於Breakpoint
應該如何設定,各個CSS
框架有本身的規定:
tailwindcss
// tailwind.config.js module.exports = { theme: { screens: { 'sm': '640px', // => @media (min-width: 640px) { ... } 'md': '768px', // => @media (min-width: 768px) { ... } 'lg': '1024px', // => @media (min-width: 1024px) { ... } 'xl': '1280px', // => @media (min-width: 1280px) { ... } } } }
tailwindcss
將Breakpoint
設置爲了640px
、768px
、1024px
、1280px
;
Bootstrap
/* 超小屏幕(手機,小於 768px) */ /* 沒有任何媒體查詢相關的代碼,由於這在 Bootstrap 中是默認的(還記得 Bootstrap 是移動設備優先的嗎?) */ /* 小屏幕(平板,大於等於 768px) */ @media (min-width: @screen-sm-min) { ... } /* 中等屏幕(桌面顯示器,大於等於 992px) */ @media (min-width: @screen-md-min) { ... } /* 大屏幕(大桌面顯示器,大於等於 1200px) */ @media (min-width: @screen-lg-min) { ... }
Bootrap
將Breakpoint
設置爲了768px
、 992px
、1200px
;
它是一個寫在HTML
head 標籤裏面的 meta
標籤。這個設定是爲了告訴手機瀏覽器,將網頁的寬度設定爲手機屏幕的寬度。
<head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head>
這個標籤是告訴手機瀏覽器,這個網頁是支持響應式的。只有加上了這個標籤媒體查詢(Media Query
)對於小屏幕寬度的設定纔會生效;
若是你的顯示器不是高清的,解像度設置爲1920 x 1080
;則表示屏幕橫向由1920
個點組成,縱向由1080
個點組成。
而若是是高清屏幕,一個單位解像度就是有多個點組成的。
爲了在屏幕中顯示足夠清晰的圖片,就須要將圖片的尺寸放大兩倍到三倍;
如何作到在屏幕中顯示高清圖像?最簡單的作法就是將600px * 600px
的圖片以300px * 300px
的大小顯示。
爲了顯示高清圖像,咱們能夠提供同一張圖片的三種尺寸(1x
、2x
、3x
)。好比顯示圖片的框大小爲300px * 300px
:
<picture> <source srcset="https://placehold.it/600x600 2x, https://placehold.it/900x900 3x"> <img src="https://placehold.it/300x300"> </picture>
這樣設備就會根據高清支持程度加載對應的尺寸的圖片了,如支持2x
高清顯示的就加載尺寸爲600px * 600px
的圖片;
當屏幕大小發生變化時,字體大小也應該跟着變化。因此推薦使用相對單位rem
和vh/vw
;
部分參考自CodingStartup起碼課