(給前端速報加星標,提升前端技能)
作者:神三元
https://juejin.im/post/5da282015188257d2a1c9e1d
一、讓一個元素水平垂直居中,到底有多少種方案?width和margin實現。margin: 0 auto;
絕對定位和margin-left: -width/2, 前提是父元素position: relative
table標籤配合margin左右auto實現水平居中。使用table標籤(或直接將塊級元素設值為display:table),再通過給該標籤添加左右margin為auto。
inline-block實現水平居中方法。display:inline-block和text-align:center實現水平居中。
絕對定位+transform,translateX可以移動本身元素的50%。
flex布局使用justify-content:center
利用line-height實現居中,這種方法適合純文字類
通過設置父容器相對定位,子級設置絕對定位,標籤通過margin實現自適應居中
彈性布局flex:父級設置display: flex; 子級設置margin為auto實現自適應居中
父級設置相對定位,子級設置絕對定位,並且通過位移transform實現
table布局,父級通過轉換成表格形式,然後子級設置vertical-align實現。(需要注意的是:vertical-align: middle使用的前提條件是內聯元素以及display值為table-cell的元素)。
浮動布局簡介:當元素浮動以後可以向左或向右移動,直到它的外邊緣碰到包含它的框或者另外一個浮動元素的邊框為止。元素浮動以後會脫離正常的文檔流,所以文檔的普通流中的框就變現的好像浮動元素不存在一樣。
優點這樣做的優點就是在圖文混排的時候可以很好的使文字環繞在圖片周圍。另外當元素浮動了起來之後,它有著塊級元素的一些性質例如可以設置寬高等,但它與inline-block還是有一些區別的,第一個就是關於橫向排序的時候,float可以設置方向而inline-block方向是固定的;還有一個就是inline-block在使用時有時會有空白間隙的問題
最明顯的缺點就是浮動元素一旦脫離了文檔流,就無法撐起父元素,會造成父級元素高度塌陷。
添加額外標籤
<div> //添加額外標籤並且添加clear屬性 <div style="clear:both"></div> //也可以加一個br標籤</div>父級添加overflow屬性,或者設置高度
<div style="overflow:hidden">//auto 也可以 //將父元素的overflow設置為hidden <div></div></div>建立偽類選擇器清除浮動(推薦)
//在css中添加:after偽元素.parent:after{ /* 設置添加子元素的內容是空 */ content: ''; /* 設置添加子元素為塊級元素 */ display: block; /* 設置添加的子元素的高度0 */ height: 0; /* 設置添加子元素看不見 */ visibility: hidden; /* 設置clear:both */ clear: both;}<div> <div></div></div>三、 使用display:inline-block會產生什麼問題?解決方法?問題復現
問題: 兩個display:inline-block元素放到一起會產生一段空白。
如代碼:
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .container { width: 800px; height: 200px; }
.left { font-size: 14px; background: red; display: inline-block; width: 100px; height: 100px; }
.right { font-size: 14px; background: blue; display: inline-block; width: 100px; height: 100px; }</style> </head> <body> <div> <div> 左 </div> <div> 右 </div> </div> </body></html>效果如下:
產生空白的原因元素被當成行內元素排版的時候,元素之間的空白符(空格、回車換行等)都會被瀏覽器處理,根據CSS中white-space屬性的處理方式(默認是normal,合併多餘空白),原來HTML代碼中的回車換行被轉成一個空白符,在字體不為0的情況下,空白符佔據一定寬度,所以inline-block的元素之間就出現了空隙。
解決辦法1. 將子元素標籤的結束符和下一個標籤的開始符寫在同一行或把所有子標籤寫在同一行<div> <div> 左 </div><div> 右 </div></div>2. 父元素中設置font-size: 0,在子元素上重置正確的font-size
.container{ width:800px; height:200px; font-size: 0;}3. 為子元素設置float:left
.left{ float: left; font-size: 14px; background: red; display: inline-block; width: 100px; height: 100px;}//right是同理四、布局題:div垂直居中,左右10px,高度始終為寬度一半
問題描述: 實現一個div垂直居中, 其距離屏幕左右兩邊各10px, 其高度始終是寬度的50%。同時div中有一個文字A,文字需要水平垂直居中。
思路一:利用height:0; padding-bottom: 50%;<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> *{ margin: 0; padding: 0; } html, body { height: 100%; width: 100%; } .outer_wrapper { margin: 0 10px; height: 100%; /* flex布局讓塊垂直居中 */ display: flex; align-items: center; } .inner_wrapper{ background: red; position: relative; width: 100%; height: 0; padding-bottom: 50%; } .box{ position: absolute; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-size: 20px; }</style> </head> <body> <div> <div> <div>A</div> </div> </div> </body></html>強調兩點:
padding-bottom究竟是相對於誰的?
答案是相對於父元素的width值。
那麼對於這個out_wrapper的用意就很好理解了。CSS呈流式布局,div默認寬度填滿,即100%大小,給out_wrapper設置margin: 0 10px;相當於讓左右分別減少了10px。
父元素相對定位,那絕對定位下的子元素寬高若設為百分比,是相對誰而言的?
相對於父元素的(content + padding)值, 注意不含border
延伸:如果子元素不是絕對定位,那寬高設為百分比是相對於父元素的寬高,標準盒模型下是content, IE盒模型是content+padding+border。
思路二: 利用calc和vw<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { padding: 0; margin: 0; }
html, body { width: 100%; height: 100%; }
.wrapper { position: relative; width: 100%; height: 100%; }
.box { margin-left: 10px; /* vw是視口的寬度, 1vw代表1%的視口寬度 */ width: calc(100vw - 20px); /* 寬度的一半 */ height: calc(50vw - 10px); position: absolute; background: red; /* 下面兩行讓塊垂直居中 */ top: 50%; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; font-size: 20px; }</style> </head> <body> <div> <div>A</div> </div> </body></html>
效果如下:
五、CSS如何進行品字布局?第一種<!doctype html><html>
<head> <meta charset="utf-8"> <title>品字布局</title> <style> * { margin: 0; padding: 0; } body { overflow: hidden; } div { margin: auto 0; width: 100px; height: 100px; background: red; font-size: 40px; line-height: 100px; color: #fff; text-align: center; }
.div1 { margin: 100px auto 0; }
.div2 { margin-left: 50%; background: green; float: left; transform: translateX(-100%); }
.div3 { background: blue; float: left; transform: translateX(-100%); }</style></head>
<body> <div>1</div> <div>2</div> <div>3</div></body>
</html>
效果:
第二種(全屏版)<!doctype html><html> <head> <meta charset="utf-8"> <title>品字布局</title> <style> * { margin: 0; padding: 0; }
div { width: 100%; height: 100px; background: red; font-size: 40px; line-height: 100px; color: #fff; text-align: center; }
.div1 { margin: 0 auto 0; }
.div2 { background: green; float: left; width: 50%; }
.div3 { background: blue; float: left; width: 50%; }</style> </head>
<body> <div>1</div> <div>2</div> <div>3</div> </body></html>
效果:
六、CSS如何進行聖杯布局聖杯布局如圖:
而且要做到左右寬度固定,中間寬度自適應。
1.利用flex布局<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .header,.footer{ height:40px; width:100%; background:red; } .container{ display: flex; } .middle{ flex: 1; background:yellow; } .left{ width:200px; background:pink; } .right{ background: aqua; width:300px; }</style></head><body> <div>這裡是頭部</div> <div> <div>左邊</div> <div>中間部分</div> <div>右邊</div> </div> <div>這裡是底部</div></body></html>
2.float布局(全部float:left)<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .header, .footer { height: 40px; width: 100%; background: red; }
.footer { clear: both; }
.container { padding-left: 200px; padding-right: 250px; }
.container div { position: relative; float: left; }
.middle { width: 100%; background: yellow; }
.left { width: 200px; background: pink; margin-left: -100%; left: -200px; }
.right { width: 250px; background: aqua; margin-left: -250px; left: 250px; }</style></head>
<body> <div>這裡是頭部</div> <div> <div>中間部分</div> <div>左邊</div> <div>右邊</div> </div> <div>這裡是底部</div></body>
</html>這種float布局是最難理解的,主要是浮動後的負margin操作,這裡重點強調一下。
設置負margin和left值之前是這樣子:
左邊的盒子設置margin-left: -100%是將盒子拉上去,效果:
.left{ /* ... */ margin-left: -100%;}然後向左移動200px來填充空下來的padding-left部分
.left{ margin-left: -100%; left: -200px;}效果呈現:
右邊的盒子設置margin-left: -250px後,盒子在該行所佔空間為0,因此直接到上面的middle塊中,效果:
.right{ /* ... */ margin-left: -250px;}然後向右移動250px, 填充父容器的padding-right部分:
.right{ /* ... */ margin-left: -250px; left: 250px;}現在就達到最後的效果了:
3.float布局(左邊float: left, 右邊float: right)<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .header, .footer { height: 40px; width: 100%; background: red; } .container{ overflow: hidden; }
.middle { background: yellow; }
.left { float: left; width: 200px; background: pink; }
.right { float: right; width: 250px; background: aqua; }</style></head>
<body> <div>這裡是頭部</div> <div> <div>左邊</div> <div>右邊</div> <div>中間部分</div> </div> <div>這裡是底部</div></body>
</html>4. 絕對定位
<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .header, .footer { height: 40px; width: 100%; background: red; } .container{ min-height: 1.2em; position: relative; }
.container>div { position: absolute; }
.middle { left: 200px; right: 250px; background: yellow; }
.left { left: 0; width: 200px; background: pink; }
.right { right: 0; width: 250px; background: aqua; }</style></head>
<body> <div>這裡是頭部</div> <div> <div>左邊</div> <div>右邊</div> <div>中間部分</div> </div> <div>這裡是底部</div></body>
</html>5.grid布局
<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> body{ display: grid; } #header{ background: red; grid-row:1; grid-column:1/5; }
#left{ grid-row:2; grid-column:1/2; background: orange; } #right{ grid-row:2; grid-column:4/5; background: cadetblue; } #middle{ grid-row:2; grid-column:2/4; background: rebeccapurple } #footer{ background: gold; grid-row:3; grid-column:1/5; }</style></head>
<body> <div id="header">header</div> <div id="left">left</div> <div id="middle">middle</div> <div id="right">right</div> <div id="footer">footer</footer></div>
</body>
</html>看看grid布局,其實也挺簡單的吧,裡面的參數應該不言而喻了。
另外說一點,到2019年為止,grid現在絕大多數瀏覽器已經可以兼容了,可以著手使用了。
當然,還有table布局,年代比較久遠了,而且對SEO不友好,知道就可以,這裡就不浪費篇幅了。
七、CSS如何實現雙飛翼布局?有了聖杯布局的鋪墊,雙飛翼布局也就問題不大啦。這裡採用經典的float布局來完成。
<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .container { min-width: 600px; } .left { float: left; width: 200px; height: 400px; background: red; margin-left: -100%; } .center { float: left; width: 100%; height: 500px; background: yellow; } .center .inner { margin: 0 200px; } .right { float: left; width: 200px; height: 400px; background: blue; margin-left: -200px; }</style></head>
<body> <article> <div> <div>雙飛翼布局</div> </div> <div></div> <div></div></article></body>
</html>複製代碼
八、什麼是BFC?什麼條件下會觸發?渲染規則?應用場景有哪些?
1.什麼是BFC?W3C對BFC的定義如下:浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不為"visiable"的塊級盒子,都會為他們的內容創建新的BFC(Block Fromatting Context, 即塊級格式上下文)。
2.觸發條件一個HTML元素要創建BFC,則滿足下列的任意一個或多個條件即可:下列方式會創建塊格式化上下文:
根元素()
浮動元素(元素的 float 不是 none)
絕對定位元素(元素的 position 為 absolute 或 fixed)
行內塊元素(元素的 display 為 inline-block)
表格單元格(元素的 display為 table-cell,HTML表格單元格默認為該值)
表格標題(元素的 display 為 table-caption,HTML表格標題默認為該值)
匿名表格單元格元素(元素的 display為 table、table-row、 table-row-group、table-header-group、table-footer-group(分別是HTML table、row、tbody、thead、tfoot的默認屬性)或 inline-table)
overflow 值不為 visible 的塊元素-彈性元素(display為 flex 或 inline-flex元素的直接子元素)
網格元素(display為 grid 或 inline-grid 元素的直接子元素)等等。
3.BFC渲染規則(1)BFC垂直方向邊距重疊
(2)BFC的區域不會與浮動元素的box重疊
(3)BFC是一個獨立的容器,外面的元素不會影響裡面的元素
(4)計算BFC高度的時候浮動元素也會參與計算
4.應用場景1. 防止浮動導致父元素高度塌陷現有如下頁面代碼:
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .container { border: 10px solid red; } .inner { background: #08BDEB; height: 100px; width: 100px; }</style> </head> <body> <div> <div></div> </div> </body></html>接下來將inner元素設為浮動:
.inner { float: left; background: #08BDEB; height: 100px; width: 100px; }會產生這樣的塌陷效果:
但如果我們對父元素設置BFC後, 這樣的問題就解決了:
.container { border: 10px solid red; overflow: hidden;}同時這也是清除浮動的一種方式。
2. 避免外邊距摺疊兩個塊同一個BFC會造成外邊距摺疊,但如果對這兩個塊分別設置BFC,那麼邊距重疊的問題就不存在了。
現有代碼如下:
<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .container { background-color: green; overflow: hidden; }
.inner { background-color: lightblue; margin: 10px 0; }</style></head>
<body> <div> <div>1</div> <div>2</div> <div>3</div> </div></body>
</html>此時三個元素的上下間隔都是10px, 因為三個元素同屬於一個BFC。現在我們做如下操作:
<div class="container"> <div class="inner">1</div> <div class="bfc"> <div class="inner">2</div> </div> <div class="inner">3</div> </div>style增加:
效果如下:
可以明顯地看到間隔變大了,而且是原來的兩倍,符合我們的預期。
關於CSS布局問題,先分享到這裡,後續會不斷地補充,希望對你有所啟發。如果對你有幫助的話,別忘了幫忙點個讚哦。
本文對你有幫助?請分享給更多人!
關注「前端速報」,提升前端技能!