HTML與CSS佈局技巧
阿新 • • 發佈:2020-08-17
### 一、使用`$`標識原生`DOM`元素
```
let $white = document.querySelector('.white')
```
### 二、要使用top,left等定位屬性
要先將該元素設定`position`屬性,`absolute`或者`relative`等
### 三、十種選擇器
三類基礎選擇器:
* `ID`選擇器;
* `class`選擇器;
* 標籤選擇器,`tag`;
以下為延伸的選擇器:
#### 第一種:空格
```css
.container div{
}
```
這裡選擇的是`class = "container"`的`HTML`元素內的所有`div`元素,但是不包括`container`這個元素;
#### 第二種:大於號 >
```css
.container > div{
}
```
選擇的是`container`裡面第一層的所有`div`:
![image-20200609152248659](http://ahuntsun.gitee.io/blogimagebed/img/html2css/1.png)
#### 第三種:加號 +
```css
.container + div{
}
```
選擇的是與`container`位於同一層的緊挨著的下一個`div`:
![image-20200609152425742](http://ahuntsun.gitee.io/blogimagebed/img/html2css/2.png)
注意了,`container`同一層緊挨著的下一個元素如果不是`div`,那麼該選擇器就選擇不到任何元素:
![image-20200609152525963](http://ahuntsun.gitee.io/blogimagebed/img/html2css/3.png)
#### 第四種:波浪號 ~
```css
.container ~ div{
}
```
選擇的是與`container`處於同一層級下的所有`div`:
![image-20200609152637052](http://ahuntsun.gitee.io/blogimagebed/img/html2css/4.png)
即使同一層下的`div`元素中有其他元素隔開,也不影響;
#### 第五種:星號 *
```css
*{
}
```
選擇的是所有的`HTML`元素;
可以與其他選擇器配合使用,比如:
```css
.container ~ *{
}
```
表示選取與`container`同一層下的所有元素;
![image-20200609152944276](http://ahuntsun.gitee.io/blogimagebed/img/html2css/5.png)
#### 第六種:屬性過濾器
```html
Apple
Google
Facebook
//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標籤
}
```
#### 第七種:偽類選擇器
```css
a:visited //瀏覽過該a連結後的狀態
a:hover //滑鼠移上a標籤後的狀態
.container div:nth-child(3n+0/n/even) //選擇container下的特定一組div元素;
```
> 注意:
```css
.card-container:hover .cover{
transform:rotateY(180deg)
}
//這種情況表示,當懸停在card-container標籤上時,改變.cover的樣式;而不是僅僅侷限於選擇card-container這個標籤
```
要選擇`.back`和`.cover`兩個標籤不能這樣寫呀:`.cover .back`,要這樣寫`.cover, .back;`中間要用逗號隔開;
```css
.cover, .back{
width: 100%;
height: 100%;
position: absolute;
backface-visibility: hidden;
//這裡寫transition表示之後對.cover和.back標籤樣式所做的修改(如hover)新增一個過渡過程
transition: transform .25s ease-in-out;
}
```
### 四、五中常用的CSS單位
#### px
絕對單位,`1px`代表一個畫素點,通常修改段落中文字大小時,除了修改`font-size`,還要修改`line-height`;
#### em
相對大小;`1em=多少px`,是基於目前這個容器中的`font-size`大小設定的,取決於使用`em`單位的標籤的父標籤(直系),的`font-size`;如下圖所示:
![image-20200609163009715](http://ahuntsun.gitee.io/blogimagebed/img/html2css/6.png)
上圖中,每一層`div`中的`1em`值,都取決於上一層`div`中的`font-size`值;
在用`em`單位設定文欄位落的字型大小時,只需要修改父元素的`font-size`,那麼使用`em`單位的`font-size`和`line-height`就不需要更改了,會自動等比例縮放;
![image-20200609163216033](http://ahuntsun.gitee.io/blogimagebed/img/html2css/7.png)
#### rem
也就是`root em`。它與`em`相似,唯一的不同是它是基於`html`元素的`font-size`大小來計算的,不受上一級的父標籤影響;
比如上面第一個例子,將`em`改為`rem`,則不同層(框)內的字型大小不會受到父元素的影響:
![image-20200609163433164](http://ahuntsun.gitee.io/blogimagebed/img/html2css/8.png)
優勢為,更容易計算,只需要更改`html`標籤中的`font-size`即可統一修改所有`rem`單位。可以避免元素被多層巢狀後難以預測它的實際大小。
#### vw與vh
全寫為`viewport width`和`viewport height`;它們的取值範圍為:`1~100`;
當`width:100vw`;`height:100vh`時,該元素會佔滿整個螢幕,當將父元素這樣設定後,就能夠很好地將子元素進行居中處理;
#### vmin與vmax
`vmin`代表螢幕較短的一邊,`vmax`代表螢幕較長的一邊,取值也是`1~100`;在移動端實現螢幕旋轉顯示。比如:一張正方形的圖片:
```css
img{
width:100vmin;
//width:100vmax;
}
```
當寬設為`100vmin`時,就會以螢幕較短的一邊的總長度作為圖片的邊長,即使旋轉屏幕後,邊長也不會改變;
當寬設為`100vmax`時,就會以螢幕較長的一邊的總長度作為圖片的邊長,旋轉屏幕後,邊長也不會改變,不能顯示的區域將會出現滾動軸;
### 五、Flexbox佈局
其他的佈局如`table`,`float`等都不是設計來做網頁佈局的,而`Flexbox`是第一套專門為了網頁佈局而設計的方法。
`flex`佈局的預設值為`block`,所以一開始設定了`flex`佈局(`display:flex`)的元素都會獨佔一行。
`Flex`佈局主要可以分為兩部分:`flex-container`(整個彈性盒容器)和`flex-items`(彈性盒中的元素);
`flex`全屬性實時預覽:**http://flexbox.help/**
#### Flex-container(彈性盒)相關屬性
這些屬性寫在設定為`flex-container`的標籤中;通過給標籤新增:`display:flex`;可以使該標籤成為一個`flex-container`。
##### 1.flex-direction
設定`flex-container`內的`items`的排序方向,預設值為`row`(行/水平排序),其他屬性值有:
* `column`:列/豎直排序;
* `row-reverse`:反向水平排序;
* `column-reverse`:反向豎直排序;
不同的排序方向,主軸與交叉軸不一樣:
![image-20200609170510747](http://ahuntsun.gitee.io/blogimagebed/img/html2css/9.png)
##### 2.justify-content
決定主軸的排序方向;有以下屬性值:
* `center`:主軸上居中;
* `flex-start`:主軸起始方向開始排列(預設表示左);
* `flex-end`:主軸結束方向開始排列(預設表示右);
* `space-around`:空白環繞;
* `space-between`:與`around`相似,只不過沒有了最左和最右的空白;
* `space-evenly`:空白平分;
##### 3.align-item
決定交叉軸的排序方向;有以下屬性值:
* `center`:交叉軸上居中;
* `flex-start`:交叉軸起始方向開始排列(當`flex-direction`為預設值`row`時,表示上);
* `flex-end`:交叉軸結束方向開始排列;(預設表示下)
* `space-around`:空白環繞;
* `space-between`:與`around`相似,只不過沒有了最左和最右的空白;
* `space-evenly`:空白平分;
`justify-content:center`與`align-item:center`配合使用可以使`flex-container`(彈性盒)內的`items`水平和垂直方向上居中。
##### 4.flex-wrap
* 當彈性盒內的`item`過多時,該屬性可以控制,是壓縮每個`item`寬度不換行,還是保持每個`item`寬度換行;
* `nowrap:壓縮`item`寬度,不換行;
* `wrap`:不改變`item`寬度,換行;(換行後,會將彈性盒一分為二,所以兩行`item`並不是挨在一起的)
##### 5.flex-flow
該屬性為`flex-direction`和`flex-wrap`組合的縮寫;如:
`flex-flow:row wrap;`等效於`flex-direction:row;flex-wrap:wrap;`
##### 6.align-content
這個屬性的前提條件為`flex-wrap`為`wrap`時,即有多行`flex items`時才會生效;用於設定多行`flex-items`間行與行間的對齊方式,屬性值有:
* `flex-start`:在交叉軸開始方向上排列:
![image-20200609173339929](http://ahuntsun.gitee.io/blogimagebed/img/html2css/10.png)
* `flex-end`:交叉軸結束方向上排列:
![image-20200609173423887](http://ahuntsun.gitee.io/blogimagebed/img/html2css/11.png)
* `center`:交叉軸中間:
![image-20200609173455869](http://ahuntsun.gitee.io/blogimagebed/img/html2css/12.png)
* `initial`:預設值,保持原來的樣子:
![image-20200609173537767](http://ahuntsun.gitee.io/blogimagebed/img/html2css/13.png)
* `space-around`:與上面一樣:
![image-20200609173614065](http://ahuntsun.gitee.io/blogimagebed/img/html2css/14.png)
* `space-between`:(上下)平均分空白,與`around`相似,不過消除了最左和最右的空白:
![image-20200609173720873](http://ahuntsun.gitee.io/blogimagebed/img/html2css/15.png)
* `space-evenly`:平分空白區域:
![image-20200609173654671](http://ahuntsun.gitee.io/blogimagebed/img/html2css/16.png)
#### Flew Item(盒內元素)相關屬性
##### 1.order
用於調整`flex item`(盒內元素)的排序順序,根據`order`的值按照主軸方向由小到大排序,預設值為`0`;比如`C`的`order`設定為`1`,因為它最大,所以`C`排到最後:
![image-20200609174101924](http://ahuntsun.gitee.io/blogimagebed/img/html2css/17.png)
##### 2.align-self
該屬性用於複寫`flex container` 的`align-items`屬性;也就是說`align-items`是對於全體的`flex items`做出規劃,而`align-self`則是設定個別`flex items`的排序方向:
![image-20200609174748237](http://ahuntsun.gitee.io/blogimagebed/img/html2css/18.png)
如上圖所示,由於`align-items:center;`所以整體的`flex items`是居中的,但是,設定了`align-self`的`C`和`D`會按照`align-self`的值進行重新排列;
##### 3.flex-basis
該屬性用於設定`flex-item`在主軸方向上的大小;比如,當主軸為`row`時,可以通過設定該屬性的值來修改每一個`flex-item`的寬,這樣`flex-item`原來的寬就失效了。
![image-20200609175701580](http://ahuntsun.gitee.io/blogimagebed/img/html2css/19.png)
同理,當`flex-direction:column;`即主軸為豎直方向時,`flex-basis`設定的屬性值將是每一個`flex-item`的高;
![image-20200609175717248](http://ahuntsun.gitee.io/blogimagebed/img/html2css/20.png)
如果設定為`0`的話,相當於將`width/height`設定為`0`,這樣每個`flex-item`在沒有設定`overflow:hidden;`的情況下,大小都由內容撐開;
設定為`auto`時,則按照原來設定的寬度來計算:
![image-20200609175916421](http://ahuntsun.gitee.io/blogimagebed/img/html2css/21.png)
也就是圖中的`60px`。
##### 4.flex-grow
該屬性是指在`flex-container`主軸方向上有剩餘空間的時候,`flex item`沿主軸方向擴大的設定。
比如,原來的佈局如下圖所示:
![image-20200609180532716](http://ahuntsun.gitee.io/blogimagebed/img/html2css/22.png)
將`flex-grow:1;`時:
![image-20200609180556694](http://ahuntsun.gitee.io/blogimagebed/img/html2css/23.png)
可見`flex-item`自動平分了主軸的空白空間。`1`的意思是每一個`flex-item`都佔有主軸空白空間的一份,也就是`1/3`。
設定`A`的`flex-grow:0;`則`A`保持原樣,不擴大;將`B`的`flex-grow:4;`表示先將空白區域分為(`4+1+0=6`份)而`B`佔其中的`4`份,`C`佔`1`份也就是:
![image-20200609181310047](http://ahuntsun.gitee.io/blogimagebed/img/html2css/24.png)
##### 5.flex-shrink
與`flex-grow`效果相反,即當`flex-item`超過了主軸長度,沿主軸方向怎樣縮小的設定。預設值為`1`,即為了不使`flex-item`突出整個`flex-box`會自動縮小每個`flex-item`。
如圖:當設定每個`flex-item`的`flex-shrink:0;`時即保持每個`flex-item`原來的大小,此時會超出主軸`90px`:
![image-20200609181554264](http://ahuntsun.gitee.io/blogimagebed/img/html2css/25.png)
如果這樣設定:
```css
.A{flex-shrink: 1}
.B{flex-shrink: 1}
.C{flex-shrink: 1}
```
即三個`flex-item`平分突出的部分,即`A`、`B`、`C`各縮小`30px`:
![image-20200609182007410](http://ahuntsun.gitee.io/blogimagebed/img/html2css/26.png)
如果這樣設定:
```css
.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`:
![image-20200609182234291](http://ahuntsun.gitee.io/blogimagebed/img/html2css/27.png)
##### 6.flex
這個屬性為`flex-grow`,`flex-shrink`和`flex-basis`組合起來的縮寫;
當這樣設定時:
```css
flex:1 1 auto;
//相當於
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
```
也就是說`flex-item`會按照`flex-container`(彈性盒)的主軸長度平均分配空間去放大或縮小。
當`flex-container`有空白空間的時候,同步擴大:
![image-20200609182642341](http://ahuntsun.gitee.io/blogimagebed/img/html2css/28.png)
當`flex-container`沒有空白空間時的時候,同步縮小:
![image-20200609182608310](http://ahuntsun.gitee.io/blogimagebed/img/html2css/29.png)
再如:
```css
flex: 0 1 150px
```
此時,`flex-grow:0;`即有空白空間時保持原樣,不擴大;整體來講就是隻有在`flex-container`空間不足時同步縮小,並且固定每個`flex-item`在主軸上的長度為`150px`。
![image-20200609182854611](http://ahuntsun.gitee.io/blogimagebed/img/html2css/30.png)
再如:
```css
flex:0 0 200px
```
即固定每個`flex-item`主軸方向上的長度為`200px`,無論`flex-container`有無空白空間都不擴大或縮小:
![image-20200609183154594](http://ahuntsun.gitee.io/blogimagebed/img/html2css/31.png)
##### 7.關於flex屬性簡寫的問題
當 `flex` 取值為 `none`,則計算值為 `0 0 auto`,如下是等同的:
```css
.item {flex: none;}
.item {
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
}
```
當 `flex` 取值為 `auto`,則計算值為 `1 1 auto`,如下是等同的:
```css
.item {flex: auto;}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
}
```
**這就是flex:1的真面目**
當 `flex` 取值為一個非負數字,則該數字為 `flex-grow` 值,`flex-shrink` 取 `1`,`flex-basis` 取 `0%`,如下是等同的:
```css
.item {flex: 1;}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
```
當 `flex` 取值為一個長度或百分比,則視為 `flex-basis` 值,`flex-grow` 取 `1`,`flex-shrink` 取 `1`,有如下等同情況(注意 `0%` 是一個百分比而不是一個非負數字):
```css
.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%`,如下是等同的:
```css
.item {flex: 2 3;}
.item {
flex-grow: 2;
flex-shrink: 3;
flex-basis: 0%;
}
```
當 `flex` 取值為一個非負數字和一個長度或百分比,則分別視為 `flex-grow` 和 `flex-basis` 的值,`flex-shrink` 取 `1`,如下是等同的:
```css
.item {flex: 2333 3222px;}
.item {
flex-grow: 2333;
flex-shrink: 1;
flex-basis: 3222px;
}
```
`flex` 的預設值是以上三個屬性值的組合。假設以上三個屬性同樣取預設值,則 `flex` 的預設值是 `0 1 auto`。同理,如下是等同的:
```css
.item {flex: 2333 3222 234px;}
.item {
flex-grow: 2333;
flex-shrink: 3222;
flex-basis: 234px;
}
```
#### 實戰案例一:導航欄
```html
Document
Document
```
效果圖:
![image-20200817174202894](http://ahuntsun.gitee.io/blogimagebed/img/html2css/31.6.png)
### 六、Grid佈局
佈局方式大致有四種:`Table`、`Float`、`Flexbox`、`Grid`;
`Table`佈局是最古老的佈局,現在已很少使用。`Float`曾經盛行一時,被稱為“`DIV + CSS`佈局”;而`Flexbox`和`Grid`才是真正為了網頁佈局而設計的;
`Flexbox`屬於一維(`1-Dimension`)的排版方式,而`Grid`則是二維(`2-Dimensions`)的排版方式。也就是說一個`Flexbox`容器只能控制一個方向,即水平方向或者垂直方向,如果要控制另一方向則需要再新增一層`Flexbox`容器;`Grid`容器則可以一次過控制兩個方向,這樣就可以直接定義容器中元素的位置了。
通過以下程式碼,設定一下佈局,通過一張帶標尺的背景圖片可以更直觀地對比:
```html
Grid
```
![image-20200610150143616](http://ahuntsun.gitee.io/blogimagebed/img/html2css/32.png)
可以看到預設情況下`grid-container`中的元素是這樣排列的;
#### 1.grid-row與grid-column
如果我們想讓藍色的`cell-1`佔據左上方的四格的話,從圖中可看出,目標範圍為`row`方向的`1~3`;`column`方向的`1-3`;可以這樣設定樣式:
```css
.cell-1{
background-color: blue;
grid-row: 1 / 3;
grid-column: 1 / 3;
}
```
效果為:
![image-20200610150709339](http://ahuntsun.gitee.io/blogimagebed/img/html2css/33.png)
如果想讓黃色的`cell-2`佔據`row`方向的`4-6`,`column`方向的`1-3`,則需要這樣設定:
```css
.cell-2{
background-color: yellow;
grid-row: 4 / 6;
grid-column: 1 / 3;
}
```
效果為:
![image-20200610150856801](http://ahuntsun.gitee.io/blogimagebed/img/html2css/34.png)
#### 2.grid-area
該屬性為`grid-row`和`grid-column`的簡寫,以黃色的`cell-2`為例:
```css
.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)。
實際開發時並沒有一把尺來參考,以藍色方塊為例,可以採取下列寫法:
```css
.cell-1{
background-color: yellow;
grid-row: 1 / 4;
grid-column: 2 / span 3;
}
```
意思為`ROW`方向從`1~4`,`COLUMN`方向上從`2`開始,`span 3` 表示從2開始往`COLUMN`方向延伸3格,效果如下:
![image-20200610152456571](http://ahuntsun.gitee.io/blogimagebed/img/html2css/35.png)
#### 3.Grid-Lines
如上圖所示,`grid-container`中水平和垂直方向上各有`6`條線,將整個`grid-container`空間分割成了`25`份;這些線在`CSS Grid`中被稱為`Grid Line`。這些`Grid Line`是可以命名的。首先給`ruler`換一個背景:
```css
#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;
}
```
效果為:
![image-20200610153330529](http://ahuntsun.gitee.io/blogimagebed/img/html2css/36.png)
也就是將水平方向的`Grid Line`命名為`X1~X6`;垂直方向的`Grid Line`命名為`Y1~Y6`;
可以在`grid-container`中這樣設定:
````css
#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`為例:
```css
.cell-1{
grid-row: Y1 / Y4;
grid-column: X2 / X6;
}
```
上面的程式碼表示,`ROW`方向範圍為`Y1~Y4`之間,`COLUMN`方向範圍為`X2-X6`之間。
效果為:
![image-20200610154248321](http://ahuntsun.gitee.io/blogimagebed/img/html2css/37.png)
#### 4.Grid Areas
`grid-container`中的線被稱為`grid line`,而方格則稱為`Grid Area`;我們也可以直接給特定的格子命名;
在`grid-container`中新增多兩個格子`cell-3`和`cell-4`,分別為橙色和黑色;重置`cell-1`,`cell-2`的佈局,將`ruler`換回原來的背景:
```css
//html結果
//css樣式
.cell-1{
background-color: blue;
}
.cell-2{
background-color: yellow;
}
.cell-3{
background-color: orange;
}
.cell-4{
background-color: black;
}
```
![image-20200610155051486](http://ahuntsun.gitee.io/blogimagebed/img/html2css/38.png)
隨後我們可以在`grid-container`中新增`grid-template-ares`屬性,該屬性的值與`grid-container`中的每一個格子一一對應:
```css
#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`:
```css
.cell-1{
background-color: blue;
grid-area: header;
}
```
那麼`cell-1`就佔據了`grid-area`中名字為`header`的區域,也就是第一行:
![image-20200610160137081](http://ahuntsun.gitee.io/blogimagebed/img/html2css/39.png)
隨後再分別將`cell-2`的`grid-area`設定為`nav`、`cell-3`設定為`main`、`cell-4`設值為`footer`:
```css
.cell-2{
background-color: yellow;
grid-area: nav;
}
.cell-3{
background-color: orange;
grid-area: main;
}
.cell-4{
background-color: black;
grid-area: footer;
}
```
效果為:
![image-20200610160327216](http://ahuntsun.gitee.io/blogimagebed/img/html2css/40.png)
這樣所有的元素都定位到設定好的位置上了;
將`ruler`中作為尺的背景圖去掉,就出現了熟悉的佈局了:
![image-20200610160513122](http://ahuntsun.gitee.io/blogimagebed/img/html2css/41.png)
還可以在`grid-container`中通過`row-gap`設定行距,`column-gap`設定列距;比如都設定為`10px`:
```css
#grid-container{
row-gap: 10px;
columns: 10px;
}
```
效果為:
![image-20200610160739794](http://ahuntsun.gitee.io/blogimagebed/img/html2css/42.png)
由於上下左右都多了`40px`,隨後將`grid-container`的長寬增加`40px`就可以了。
![image-20200610160957578](http://ahuntsun.gitee.io/blogimagebed/img/html2css/43.png)
#### 5.Fr
`Fr`為`Grid`中的比例單位,表示佔一份的意思。比如:
```css
#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);
}
```
### 七、上下左右居中
#### 左右置中
##### 1.display:inline/inline-block
將父元素(容器)設定`text-align:center`,就可以左右置中了;
##### 2.display:block
將元素本身的`margin-left`與`margin-right`設定為`auto`,也就是通常的:`margin: 0, auto;`就可以左右居中了;
#### 上下左右置中
##### 1.position:absolute
```css
#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%);
}
```
##### 2.Flexbox
可以這樣設定,使`body`的內容,上下左右居中:
```css
body{
min-height: 100vh;
display: flex; //將body設定為flex-container
justify-content: center; //將主軸上的flex-item居中
align-items: center; //將交叉軸上的flex-item居中
}
```
##### 3.display Table
原理為將父元素設定為表格佈局(`display:table`),裡面要居中的元素設定為表格的一個格子(`display: table-cell`),這樣`vertical-align`屬性就能對這個格子生效了;這樣設定:
```css
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
`position`有五個設定值,分別是:`static`、`absolute`、`relative`、`fixed`和`sticky`。
#### Static
`HTML`裡面所有元素的`Position`預設值都是`static`,設定了該屬性的元素,**不會脫離文件流**,會隨著`HTML`文件排版的流程(`flow`)而發生變化。
首先,搭建以下的`HTML`和`CSS`樣式:
![image-20200610170407953](http://ahuntsun.gitee.io/blogimagebed/img/html2css/44.png)
效果為:
![image-20200610170429528](http://ahuntsun.gitee.io/blogimagebed/img/html2css/45.png)
> 為了方便說明,事先為`static`類添加了樣式(下同);
隨後在`html`樣式中新增一句`"Hello World"`:
```html
Hello World
```
可以看到這個`static`的`div`就會因為這一行文字而向下移動了一點:
![image-20200610170718026](http://ahuntsun.gitee.io/blogimagebed/img/html2css/46.png)
再次改寫`HTML`和`CSS`樣式:
```html
//HTML結構
//CSS結構
.static{
position: static;
width: 360px;
height: 360px;
}
.height{
width: 750px;
height:120px;
}
```
效果如下:
![image-20200610171042887](http://ahuntsun.gitee.io/blogimagebed/img/html2css/47.png)
可以看到,`height`div高為`120px`,所以`static`的div就要相應下移`120px`;
**注意:**`position`值為`static`的元素對於`top`、`left`、`right`、`bottom`的設定值都是不會生效的;
#### Absolute
如下改寫`HTML`和`CSS`結構:
```html
//HTML結構
//CSS結構
.height{
width: 750px;
height:120px;
}
.absolute{
position: absolute;
width: 240px;
height: 240px;
right: 80px;
bottom: 60px;
}
```
效果為:
![image-20200610171527483](http://ahuntsun.gitee.io/blogimagebed/img/html2css/48.png)
如圖所示,`right`的設定值是將元素定位到與`HTML`文件右邊相距`80px`的位置;`bottom`則是將元素定位到與`HTML`文件底部相距`60px`的位置。
`absolute`元素會固定在所設定的位置,不會隨著HTML文件排版的流程移動,即**脫離文件流**。
更改樣式,加多幾個高度為`120px`的藍色`height`div:
```html
//HTML結構
//CSS結構
.height{
width: 750px;
height:120px;
}
.absolute{
position: absolute;
width: 240px;
height: 240px;
right: 80px;
bottom: 60px;
}
```
效果:
![image-20200610171928358](http://ahuntsun.gitee.io/blogimagebed/img/html2css/49.png)
可以看到並沒有影響到`absolute`元素所在的位置的。但是如果`absolute`元素所在的容器有滾動軸的話,它就會隨著滾動軸移動:
![image-20200610172053650](http://ahuntsun.gitee.io/blogimagebed/img/html2css/50.png)
再次更改樣式,新增多一個`absolute`div:
```html
//HTML結構
//CSS結構
.height{
width: 750px;
height:120px;
}
.absolute{
position: absolute;
width: 240px;
height: 240px;
right: 80px;
bottom: 60px;
}
```
乍一看頁面沒有發生變化:
![image-20200610171527483](http://ahuntsun.gitee.io/blogimagebed/img/html2css/51.png)
但是,實際上兩個`absolute`元素是重疊到一起了。可以通過將其中一個`absolute`元素的`right`設定為`100px`,證明:
```html
```
可以看到這兩個`absolute`元素確實是重疊在一起的:
![image-20200610172414731](http://ahuntsun.gitee.io/blogimagebed/img/html2css/52.png)
再次更改樣式,將`absolute`元素放在`absolute`元素內,結果會如何呢?
```html
//HTML結構
//CSS結構
.height{
width: 750px;
height:120px;
}
.absolute{
position: absolute;
width: 240px;
height: 240px;
right: 80px;
bottom: 60px;
}
```
結果是裡面的`absolute`元素的`right`與`bottom`是根據外面那層的`absolute`元素的位置去定位的。所以會再向左偏移`80px`,向上多偏移`60px`:
![image-20200610172542847](http://ahuntsun.gitee.io/blogimagebed/img/html2css/53.png)
#### Relative
新增一個`relative`div並改寫樣式:
```html
//HTML結構
//CSS結構
.height{
width: 750px;
height:120px;
}
.relative{
position: relative;
width: 360px;
height: 360px;
top: 60px;
left: 150px;
}
```
效果如圖所示:
![image-20200610173351600](http://ahuntsun.gitee.io/blogimagebed/img/html2css/54.png)
可見,`relative`與`static`是很相似的,都是會跟隨`HTML`的排版流程(文件流)移動。但是它比`Static`多了`top`、`left`、`right`、`bottom`的設定。也就是說,它在跟隨`HTML`排版流程去定位之餘,還可以通過這四個值進一步調整位置。
比如在上面增加一個`height`div:
```html
//HTML結構
```
`relative`元素就會因上方增加的內容而向下移動:
![image-20200610173729955](http://ahuntsun.gitee.io/blogimagebed/img/html2css/55.png)
除此之外,`relative`最重要的一個功能是:在它裡面的`absolute`元素會根據`relative`的位置去定位;比如在它裡面加一個`absolute`div:
```html
//HTML結構
```
會發現`absolute`元素的`right`與`bottom`是根據`relative`元素的位置去定位的:
![image-20200610174013632](http://ahuntsun.gitee.io/blogimagebed/img/html2css/56.png)
有人可能會認為這不是很正常嘛,我們將`relative`改成`static`:
````html
//HTML結構
````
可以看到,`absolute`元素會直接無視包含它的`static`元素:
![image-20200610174256871](http://ahuntsun.gitee.io/blogimagebed/img/html2css/57.png)
**總結:**`relative`相對於`static`,主要增加了兩大功能:
* **第一:**`relative`具備了`top`、`left`、`right`、`bottom`的設定;
* **第二:**可以使`absolute`子元素根據它的位置去定位,也就是**子絕父相**;
#### Fixed
新增一個`fixed`div:
```html
//HTML結構
//CSS結構
.height{
width: 750px;
height:120px;
}
.fixed{
position: fixed;
width: 240px;
height: 240px;
bottom: 60px;
left: 80px;
}
```
效果為:
![image-20200610174735617](http://ahuntsun.gitee.io/blogimagebed/img/html2css/58.png)
`fixed`與`absolute`是很相似的,不同的地方有兩點:
* **第一:**`fixed`會固定到熒幕中的固定位置,即使滾動頁面,它的位置也不會發生改變;
增添多個`height`div,可以發現即使滾動頁面,`fixed`div位置也不變:
![image-20200610175105563](http://ahuntsun.gitee.io/blogimagebed/img/html2css/59.png)
* **第二:**如果`fixed` div設定了`top`、`left`、`bottom`、`right`的值,即使將它放入`relative` div中,`fixed` div 依舊會根據頁面,也就是`body`去定位,而不會根據`relative` div去定位。
改寫樣式,在`relative` div 中新增一個`fixed` div:
```html
//HTML結構
```
在`fixed` div不新增`top`、`left`、`bottom`、`right`屬性時,`fixed` div 會相對於包裹它的`relative` div 定位:
![image-20200610175658259](http://ahuntsun.gitee.io/blogimagebed/img/html2css/60.png)
當設定了`top`、`left`、`right`、`bottom`其中一些屬性之後:
```html
//HTML結構
```
`fixed` div 就會脫離包裹它的`relative` div 的束縛,而根據`body`進行定位:
![image-20200610175854436](http://ahuntsun.gitee.io/blogimagebed/img/html2css/61.png)
#### Sticky
新增`sticky` div 改寫樣式:
```html
//HTML結構
//CSS結構
.height{
width: 750px;
height:120px;
}
.sticky{
position: sticky;
width: 240px;
height: 90px;
top: 0;
}
```
可以看到,頁面出現了滾動軸:
![image-20200610180208945](http://ahuntsun.gitee.io/blogimagebed/img/html2css/62.png)
隨後滾動頁面:
![image-20200610180226220](http://ahuntsun.gitee.io/blogimagebed/img/html2css/63.png)
可以發現,`sticky` div 在滾動的過程中,當貼到頁面頂部的時候,就會固定在頁面頂部,也就是"粘住了";之所以會粘住是因為我們設定了`sticky` div 的`top`為`0`,當它距離頁面頂部`0px`的時候,就會觸發`top:0px;`這一屬性。
### 九、Block,Inline和Inline-Block
`HTML`元素大致上預設分為兩種形態,一種為`Block`,另一種為`Inline`。`Block`為區塊的意思,`Inline`為內聯的意思。
#### 1.Block
`Block`元素會獨佔一行,比如兩個段落,即使原始碼中沒有空格,顯示的兩段文字也會隔開(因為`p`標籤是塊元素):
![image-20200611110152521](http://ahuntsun.gitee.io/blogimagebed/img/html2css/64.png)
由於塊元素是獨佔一行的,所以,即使一行中有空間也不允許兩個塊元素左右排列,如下圖所示將`p`標籤的寬度設定為`50%`後,兩個`P`標籤也不會左右排列。
![image-20200611110314773](http://ahuntsun.gitee.io/blogimagebed/img/html2css/65.png)
> `HTML`原始碼中會將多個空格合併為一個空格進行顯示,若要加多個空格可以新增:` (no-break-space)`
`Block`元素的特點為:
* 單獨佔一行,`Block`元素之間只能上下排列;
* 元素大小可以通過`width`和`height`設定;
常見預設為`Block`的標籤有:`div`、`p`、`h1`到`h6`、`ul`等。
#### 2.Inline
如下圖所示,在`p`標籤中加入 `strong` 標籤,並設定樣式:
![image-20200611110735956](http://ahuntsun.gitee.io/blogimagebed/img/html2css/66.png)
這裡的 `strong` 就是`inline`內聯元素。它的特點為:
* `Inline`標籤之間可以左右排列;
* `inline`元素的大小由所包含的內容決定,不受`width`和`height`影響;
常見預設為`inline`的標籤有 `a` 、 `strong` 、 `span`等。
#### 3.Inline-Block
它結合了`Inline`和`Block`兩者的特性,既可以設定寬度和高度,又可以與其他`Inline`元素並排。
比如在段落的最後面加一個超連結按鈕,就可以採用`Inline-Block`:
樣式為:
```html
//HTML
Inline-block //CSS div{ width: 50%; } span{ } strong{ display: inline-block; } div, span, strong{ background-color: black; color: white; } ``` 效果如下: ![image-20200611114618768](http://ahuntsun.gitee.io/blogimagebed/img/html2css/68.png) 隨後給body新增樣式: ```css body{ text-align: center } ``` 可以看到`Inline`與`Inline-Blick`元素都水平居中了,而`block`元素只是將裡面的文字居中了,`block`元素本身並沒有居中: ![image-20200611114822580](http://ahuntsun.gitee.io/blogimagebed/img/html2css/69.png) 這是因為**Inline與Inline-Blick**二者的容器的大小都是由內容決定,所以`text-align:center`對整個元素都有效;而對`Block`元素無效,只對該元素內部的文字有效。要想讓`block`元素和其中內容都居中,需要設定`block`元素的`margin`樣式: ```css div{ width: 50%; margin-left: auto; margin-right: auto; } ``` 此時就能達到水平居中了: ![image-20200611115317584](http://ahuntsun.gitee.io/blogimagebed/img/html2css/70.png) **總結:**居中方法: * **Inline與Inline-Blick:** ```css body{ text-align: center } ``` * **Block:** ```css body{ text-align: center } div{ width: 50%; margin-left: auto; margin-right: auto; } ``` ### 十、Box Model `CSS Box Model`一共包括了四種屬性:`Content`、`Padding`、`Border`和`Margin`。 它們的結構和排序順序是這樣的: ![image-20200611120134863](http://ahuntsun.gitee.io/blogimagebed/img/html2css/71.png) 由內往外分別是:`content`、`padding`、`border`、`margin`。 關於`margin`與`padding`: * 一個屬性值時:上下左右; * 兩個屬性值時:上下, 左右; * 三個屬性值時:上,左右,下; * 四個屬性值時:上、右、下、左;(順時針) #### 1.標準盒子模型 ![image-20200611120713799](http://ahuntsun.gitee.io/blogimagebed/img/html2css/72.png) 在標準盒子模型中,`Width = content`; 也就是說只要改變了`content`、`padding`、`border`、`margin`中的任一個值,都會撐大整個盒子。 #### 2.怪異(IE)盒子模型 ![image-20200611120702455](http://ahuntsun.gitee.io/blogimagebed/img/html2css/73.png) 在怪異盒子模型中,`Width = content + padding + border + margin`; 一旦設定了元素的`width`大小後,相當於固定了整個盒子的大小。再去改變上面的四個屬性,盒子整體的大小不變,四個屬性自動調整。 利用這一特性,就可以隨便更改盒子的`margin`、`content`、`padding`、`border`屬性值而不用擔心撐大盒子了。 盒子預設為標準盒子模型,即`box-sizing:content-box;`可以通過:`box-sizing:border-box`,來將它設定為怪異盒子模型。 #### 3.Inline元素使用margin與padding * 使用`margin`時:只會左右生效,上下會失效: ![image-20200611123229359](http://ahuntsun.gitee.io/blogimagebed/img/html2css/74.png) * 使用`padding`時:上下左右都生效,只不過只有左右隔開了,改變了佈局;上下沒有改變佈局,只是覆蓋了: ![image-20200611123307105](http://ahuntsun.gitee.io/blogimagebed/img/html2css/75.png) 可以這樣記憶,`inline`元素的`margin`和`padding`屬性都不會影響**垂直方向**上的佈局。 #### 4.inline-block使用margin與padding `inline-block`元素的`margin`和`paddind`屬性在上下左右四個方向上都會生效: ![image-20200611123653901](http://ahuntsun.gitee.io/blogimagebed/img/html2css/76.png) #### 5.關於margin-top與margin-bottom摺疊問題 上下排列的兩個塊級元素,分別設定`margin-bottom`和`margin-top`;整體的空隔取二者的最大值,而不會疊加;解決方法為:在中間加入一個有高度的元素,比如`1px`的`border`(通常通過為元素`::after`新增); ### 十一、瀑布流 先來看看採用瀑布流佈局的典型例子:`Pinterest`:世界上最大的圖片社交分享網站。 ![image-20200611194344036](http://ahuntsun.gitee.io/blogimagebed/img/html2css/77.png) 最簡單實現的方法是使用別人寫好的外掛比如: * **Masonry.js** ![image-20200611194625690](http://ahuntsun.gitee.io/blogimagebed/img/html2css/78.png) * **lsotope.js** ![image-20200611195048899](http://ahuntsun.gitee.io/blogimagebed/img/html2css/79.png) 它們實現的原理是通過`javascript`計算一共有多少個方格,在計算每一個方格的寬度和高度,因容器的寬度可以放置多少列等等要求。將全部方格的`position`都設定為`absolute`,逐一計算它們的`top`和`left`實現定位。 由於所有方格的位置是計算出來的,當頁面寬度變化時可以實現動態地重新排列。 下面介紹使用純`CSS`實現瀑布流的兩種方法,並分析它們的限制: #### 1.CSS Column *方法一:僅適用`column-count`和`column-gap`兩個屬性實現* 程式碼為: ```htmlColumn 實現瀑布流佈局
```
效果為:
![image-20200611201813318](http://ahuntsun.gitee.io/blogimagebed/img/html2css/80.png)
**優點:**程式碼簡單,只需要使用`column-count`和`column-gap`兩個屬性即可;
**缺點:**圖片的排列順序是從第一列的上到下,再到下一行的上到下;
#### 2.Flexbox
沿用第一種方法的`HTML`結構,更改樣式如下:
```css
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)
}
```
此時效果與第一種方法一致:
![image-20200611205006900](http://ahuntsun.gitee.io/blogimagebed/img/html2css/81.png)
不過,可以通過`flex`佈局中的`order`屬性,更改它的排序順序。新增如下樣式:
```css
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時,可以選取到1、5、9、13 */
.item:nth-child(4n+1){
order: 1;
}
/* 選取第二行的item,當n=0~3時,可以選取到2、6、10、14 */
.item:nth-child(4n+2){
order: 2;
}
/* 選取第三行的item,當n=0~3時,可以選取到3、7、11、15 */
.item:nth-child(4n+3){
order: 3;
}
/* 選取第四行的item,當n=0~3時,可以選取到4、8、12、16 */
.item:nth-child(4n){
order: 4;
}
```
效果為:
![image-20200611205852571](http://ahuntsun.gitee.io/blogimagebed/img/html2css/82.png)
這種方法主要使用了`Flex`中的`order`屬性;
**存在的問題**:需要設定`Flex`容器的高度。所以我們需要知道內容加起來的高度是多少。還要考慮要分為多少個豎行。去為`Flex`容器計算一個合理的高度。比如改變頁面的寬度,會出現只需要三個豎行就能容納圖片的情況:
![image-20200611210241606](http://ahuntsun.gitee.io/blogimagebed/img/html2css/83.png)
而這種情況我們是不希望看到的;
**綜上所述:要實現瀑布流簡單時可以使用column,完美實現時還需採用js套件。**
### 十二、Float
元老級的佈局屬性,幾乎不存在相容性問題,連`IE6`也支援。
`Float`最初是為了解決"繞圖排文"問題設計的。不使用`Float`時:
```html
- Home
- About
- Products
- Protfolio
- Contact
Flexbox Example
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.//some words More...
//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`標籤以塊級標籤特性了: ![image-20200611112041723](http://ahuntsun.gitee.io/blogimagebed/img/html2css/67.png) #### 4.對齊方式 所有`HTML`元素都可以通過更改`display`屬性將它設定為`Blcok`、`Inline`、`Inline-Block`; 改寫如下樣式: ```html //HTML Block InlineInline-block //CSS div{ width: 50%; } span{ } strong{ display: inline-block; } div, span, strong{ background-color: black; color: white; } ``` 效果如下: ![image-20200611114618768](http://ahuntsun.gitee.io/blogimagebed/img/html2css/68.png) 隨後給body新增樣式: ```css body{ text-align: center } ``` 可以看到`Inline`與`Inline-Blick`元素都水平居中了,而`block`元素只是將裡面的文字居中了,`block`元素本身並沒有居中: ![image-20200611114822580](http://ahuntsun.gitee.io/blogimagebed/img/html2css/69.png) 這是因為**Inline與Inline-Blick**二者的容器的大小都是由內容決定,所以`text-align:center`對整個元素都有效;而對`Block`元素無效,只對該元素內部的文字有效。要想讓`block`元素和其中內容都居中,需要設定`block`元素的`margin`樣式: ```css div{ width: 50%; margin-left: auto; margin-right: auto; } ``` 此時就能達到水平居中了: ![image-20200611115317584](http://ahuntsun.gitee.io/blogimagebed/img/html2css/70.png) **總結:**居中方法: * **Inline與Inline-Blick:** ```css body{ text-align: center } ``` * **Block:** ```css body{ text-align: center } div{ width: 50%; margin-left: auto; margin-right: auto; } ``` ### 十、Box Model `CSS Box Model`一共包括了四種屬性:`Content`、`Padding`、`Border`和`Margin`。 它們的結構和排序順序是這樣的: ![image-20200611120134863](http://ahuntsun.gitee.io/blogimagebed/img/html2css/71.png) 由內往外分別是:`content`、`padding`、`border`、`margin`。 關於`margin`與`padding`: * 一個屬性值時:上下左右; * 兩個屬性值時:上下, 左右; * 三個屬性值時:上,左右,下; * 四個屬性值時:上、右、下、左;(順時針) #### 1.標準盒子模型 ![image-20200611120713799](http://ahuntsun.gitee.io/blogimagebed/img/html2css/72.png) 在標準盒子模型中,`Width = content`; 也就是說只要改變了`content`、`padding`、`border`、`margin`中的任一個值,都會撐大整個盒子。 #### 2.怪異(IE)盒子模型 ![image-20200611120702455](http://ahuntsun.gitee.io/blogimagebed/img/html2css/73.png) 在怪異盒子模型中,`Width = content + padding + border + margin`; 一旦設定了元素的`width`大小後,相當於固定了整個盒子的大小。再去改變上面的四個屬性,盒子整體的大小不變,四個屬性自動調整。 利用這一特性,就可以隨便更改盒子的`margin`、`content`、`padding`、`border`屬性值而不用擔心撐大盒子了。 盒子預設為標準盒子模型,即`box-sizing:content-box;`可以通過:`box-sizing:border-box`,來將它設定為怪異盒子模型。 #### 3.Inline元素使用margin與padding * 使用`margin`時:只會左右生效,上下會失效: ![image-20200611123229359](http://ahuntsun.gitee.io/blogimagebed/img/html2css/74.png) * 使用`padding`時:上下左右都生效,只不過只有左右隔開了,改變了佈局;上下沒有改變佈局,只是覆蓋了: ![image-20200611123307105](http://ahuntsun.gitee.io/blogimagebed/img/html2css/75.png) 可以這樣記憶,`inline`元素的`margin`和`padding`屬性都不會影響**垂直方向**上的佈局。 #### 4.inline-block使用margin與padding `inline-block`元素的`margin`和`paddind`屬性在上下左右四個方向上都會生效: ![image-20200611123653901](http://ahuntsun.gitee.io/blogimagebed/img/html2css/76.png) #### 5.關於margin-top與margin-bottom摺疊問題 上下排列的兩個塊級元素,分別設定`margin-bottom`和`margin-top`;整體的空隔取二者的最大值,而不會疊加;解決方法為:在中間加入一個有高度的元素,比如`1px`的`border`(通常通過為元素`::after`新增); ### 十一、瀑布流 先來看看採用瀑布流佈局的典型例子:`Pinterest`:世界上最大的圖片社交分享網站。 ![image-20200611194344036](http://ahuntsun.gitee.io/blogimagebed/img/html2css/77.png) 最簡單實現的方法是使用別人寫好的外掛比如: * **Masonry.js** ![image-20200611194625690](http://ahuntsun.gitee.io/blogimagebed/img/html2css/78.png) * **lsotope.js** ![image-20200611195048899](http://ahuntsun.gitee.io/blogimagebed/img/html2css/79.png) 它們實現的原理是通過`javascript`計算一共有多少個方格,在計算每一個方格的寬度和高度,因容器的寬度可以放置多少列等等要求。將全部方格的`position`都設定為`absolute`,逐一計算它們的`top`和`left`實現定位。 由於所有方格的位置是計算出來的,當頁面寬度變化時可以實現動態地重新排列。 下面介紹使用純`CSS`實現瀑布流的兩種方法,並分析它們的限制: #### 1.CSS Column *方法一:僅適用`column-count`和`column-gap`兩個屬性實現* 程式碼為: ```html
一段文字
``` 效果為: ![image-20200611211447353](http://ahuntsun.gitee.io/blogimagebed/img/html2css/84.png) 為加上`float`屬性就可以實現"繞圖排文"了: ```css img{ float:left;// 脫離文件流 display: block;// join文件流 margin-right:20px; } ``` ![image-20200611211734588](http://ahuntsun.gitee.io/blogimagebed/img/html2css/85.png) #### 1.清除浮動 設定樣式: ```html //HTML 一段文字 一段文字 一段文字一段文字
//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%; } ``` 此時的效果為(大致): ![image-20200611215104318](http://ahuntsun.gitee.io/blogimagebed/img/html2css/86.png) 三個浮動的`div`並沒有因為被`container` div 包裹著而與`p`標籤隔開,這是因為,三個`div`都浮動起來了,與`container` div 不在一個平面上。就好像橡膠圈一樣`container`捆不住這些浮動的`div`,所以會出現這樣的情況,即`container` div 出現了**元素坍塌**; 為了恢復正常就需要清除父容器`container` div 中子元素的浮動了,有以下三種方法: * **第一:clearfix** 這個類的作用為結束`float`繼續影響後續內容的排版;使用方法為在父容器`container` div 同一層加上一個塊級元素,再新增如下的樣式: ```html //HTML //CSS .clearfix{ clear:both; } ``` 現在,排版就正確了: ![image-20200611215903816](http://ahuntsun.gitee.io/blogimagebed/img/html2css/87.png) 這種方式並不優雅,不通過新增`HTML`塊級標籤,而是通過偽類`after`的方式新增,樣式如下: ```html //HTML //CSS .container::after{ content: ''; clear:both; display:block; } ``` * **第二:overflow** 只需要將父容器`container` div 的`overflow`屬性設定為`visible`以外的任何一個值,比如`auto`或`hidden`。 ```html //HTML //CSS .container{ overflow:auto; } ``` 此時這個`container` div 就會變成一個`BFC`(`Block Formatting Context`:塊級視覺化上下文),`BFC`會形成一個區域性的塊級,達到"隔斷"的效果。 * **第三:display** 為父容器`container` div 新增`display:flow-root;`即可將其變成一個`BFC`。 ```css //HTML //CSS .container{ display: flow-root; } ``` 不過這個屬性較新,並且所有的IE版本都不支援: ![image-20200611225141683](http://ahuntsun.gitee.io/blogimagebed/img/html2css/88.png) ### 十三、響應式(Responsive)佈局 響應式佈局指的是網頁會因不同設別的螢幕大小,例如電腦、手機、平板等裝置。自動調整版面佈局,圖片及字型大小等。使網頁適應在不同大小的熒幕下顯示。 分別有以下幾個方面: #### 1.Media Query(媒體查詢) 可以通過設定`Media Query`的`Breakpoint`(斷點),並且設定當符合這個`Breakpoint`的時候,改變`CSS`樣式。 例如: ```css @media screen and (max-width: 360px){ } ``` 在上面的設定中,`screen`指有螢幕的裝置;`max-width: 360px`表示`Query`或是叫`Breakpoint`,指螢幕最大寬度為`360px`;通過`and`組合起來就是:當裝置有螢幕,並且最大寬度為`360px`以下的情況下,觸發花括號內的`CSS`樣式。 還可以設定螢幕寬度較寬時的樣式: ```css @media screen and (min-width: 960px){ } ``` 上述設定指的是,螢幕寬度大於`960px`的情況下觸發花括號內的`CSS`。 至於`Breakpoint`應該如何設定,各個`CSS`框架有自己的規定: * **tailwindcss** ```css // 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** ````css /* 超小螢幕(手機,小於 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`; #### 2.Meta Viewport 它是一個寫在`HTML` head 標籤裡面的 `meta`標籤。這個設定是為了告訴手機瀏覽器,將網頁的寬度設定為手機螢幕的寬度。 ```html ``` 這個標籤是告訴手機瀏覽器,這個網頁是支援響應式的。只有加上了這個標籤媒體查詢(`Media Query`)對於小螢幕寬度的設定才會生效; #### 3.Resolution(解像度) 如果你的顯示器不是高清的,解像度設定為`1920 x 1080`;則表示螢幕橫向由`1920`個點組成,縱向由`1080`個點組成。 而如果是高清螢幕,一個單位解像度就是有多個點組成的。 為了在螢幕中顯示足夠清晰的圖片,就需要將圖片的尺寸放大兩倍到三倍; #### 4.Image Size 如何做到在螢幕中顯示高清影象?最簡單的做法就是將`600px * 600px`的圖片以`300px * 300px` 的大小顯示。 為了顯示高清影象,我們可以提供同一張圖片的三種尺寸(`1x`、`2x`、`3x`)。比如顯示圖片的框大小為`300px * 300px`: ```html ``` 這樣裝置就會根據高清支援程度載入對應的尺寸的圖片了,如支援`2x`高清顯示的就載入尺寸為`600px * 600px`的圖片; #### 5.Font-Size 當螢幕大小發生變化時,字型大小也應該跟著變化。所以推薦使用相對單位`rem`和`vh/vw`; > 部分參考自[CodingStartup起碼課](https://space.bilibili.com/451