學習css的主要目的是爲了記住各類屬性麼?NO,最重要的是理解css的定位機制與盒子模型。
接下來,從佈局的角度來學習css的定位機制和盒子模型,學習以前仍是先來提幾個問題
css
css是用來爲頁面元素添加樣式的,在最開始的時候,開發網頁是先將各個尺寸定下來,而後使用最傳統的position/float把元素挪到對應的位置,頁面上的元素就好像一個個盒子同樣,很明顯可以得出一個結論:盒子模型是佈局的基礎,因此在學習css佈局前要先來學習盒子模型,盒子模型包括content,padding,border,margin四大部分,以下圖:
html
盒子模型通常分爲標準盒子模型和IE盒子模型,前者由w3c規定,後者由微軟規定,這兩種盒子模型能夠經過box-sizing來進行切換,它們最大的區別就是width屬性做用的範圍,標準盒子的width=content,IE盒子的width=content + padding + border,看下圖:
ios
除了標準盒子和IE盒子這種分類方法,通常還將盒子模型分紅塊級盒子模型和行內盒子模型,這個是根據不一樣的display屬性值劃分的,下面是display的可能取值:
css3
塊級盒子模型的圖在上面已經貼出了,下面是行內盒子模型的圖:
web
前面說了盒子模型包括什麼內容,對於任意的盒子模型來講,它的四部份內容能夠給它們設值也能夠不設值,這四個值中margin部分有不少能夠探討的內容,好比它能夠設置負值,這一部分之因此複雜,是由於它與display的不一樣值混合時會有不少不一樣的狀況,好比margin設負值後可能會帶來重疊,那具體重疊的狀況是怎樣的?說不一樣的重疊狀況前,先來理解一下,margin負值是什麼意思?margin的值實際上是相對於基線來進行移動,對於top,left方向,它們是以其餘元素的邊框爲基線,對於right,bottom方向它們是以自身border爲基線,具體看下圖:
瀏覽器
接下來看看不一樣的display會對margin重疊形成什麼影響
app
1.表現(測試地址:https://demo.xiaohuochai.site...)函數
2.重疊(測試地址:https://demo.xiaohuochai.site...)佈局
3.浮動(測試地址:https://demo.xiaohuochai.site...)學習
4.定位(測試地址:https://demo.xiaohuochai.site...)
margin合併(collapse)是指塊級元素的上外邊距與下外邊距有時會合併爲單個外邊距,這種現象只發生在和當前文檔流方向的相垂直的方向上,它分爲同級元素和父子元素兩種,首先是同級元素,具體代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .center{ width: 500px; background: pink; margin: 80px auto; padding: 10px; } </style> </head> <body> <div class="center">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam mollitia aut eaque nihil eos rem suscipit error id nesciunt saepe? Deserunt aspernatur, iusto facere sequi doloribus accusantium porro odio alias.</div> <div class="center">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam mollitia aut eaque nihil eos rem suscipit error id nesciunt saepe? Deserunt aspernatur, iusto facere sequi doloribus accusantium porro odio alias.</div> </body> </html>
接着是父子元素,具體代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .center{ width: 500px; background: pink; margin: 80px auto; } .inCenter{ background: blue; margin: 40px 0; padding: 10px; } </style> </head> <body> <div class="center"> <div class="inCenter">hello</div> </div> </body> </html>
最後這個比較簡單,是在佈局中經常使用的一種水平居中的方法,當頁面元素的寬度是肯定的值的時候,設置margin:0 auto;元素會進行居中,這是由於auto表明左右自適應,具體代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .center{ width: 500px; background: pink; margin: 80px auto; padding: 10px; } </style> </head> <body> <div class="center">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam mollitia aut eaque nihil eos rem suscipit error id nesciunt saepe? Deserunt aspernatur, iusto facere sequi doloribus accusantium porro odio alias.</div> </body> </html>
前面出現的邊距重疊咱們只是列出了問題可是沒有解決,這是由於要解決這樣的問題,須要瞭解另一個知識,這個知識涉及到了定位機制的內容BFC,寫在這裏,就做爲一個承前啓後的部分,那BFC究竟是什麼?
BFC(Block formatting context)直譯爲"塊級格式化上下文"。它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何佈局,而且與這個區域外部絕不相干。
簡單來講,BFC就是頁面上單獨開的一塊渲染區域,有的人把它叫作css世界的結界,很是的形象,那它是如何被觸發的?又爲何能解決邊距重疊?
首先是觸發規則:
接着是渲染規則:
最後看它怎樣解決邊距重疊,一樣的代碼,只須要添加一句overflow:hidden觸發BFC,之因此能解決重疊是由於觸發了新的bfc後與外部環境就隔開了,彼此不會影響。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .center1{ width: 500px; background: pink; margin: 80px auto; padding: 10px; } .wrapper{ overflow: hidden; } .center2{ width: 500px; background: pink; margin: 80px auto; padding: 10px; } </style> </head> <body> <div class="center1">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam mollitia aut eaque nihil eos rem suscipit error id nesciunt saepe? Deserunt aspernatur, iusto facere sequi doloribus accusantium porro odio alias.</div> <div class="wrapper"> <div class="center2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam mollitia aut eaque nihil eos rem suscipit error id nesciunt saepe? Deserunt aspernatur, iusto facere sequi doloribus accusantium porro odio alias.</div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .center{ width: 500px; background: pink; margin: 80px auto; overflow:hidden; } .inCenter{ background: blue; margin: 40px 0; padding: 10px; } </style> </head> <body> <div class="center"> <div class="inCenter">hello</div> </div> </body> </html>
上面說了盒子模型,知道了css操縱的內容具體是什麼樣的,接下來就須要把這些盒子放在頁面上,在css的定位機制中,position:absolute、relative、static、fixed有這幾個取值,先來看看這些取值的不一樣
position:absolute是將元素以瀏覽器視口爲原點或者以最近的定位元素爲原點來進行定位,具體看下面的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .wrapper{ width:500px; height:500px; background: pink; margin:200px 500px; } .absolute{ width: 100px; height:100px; position:absolute; top:50px; left:50px; background: green; } </style> </head> <body> <div class="wrapper"> <div class="absolute">absolute</div> </div> </body> </html>
接着是position:relative,他是相對於自身的位置進行偏移,具體看下面的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .wrapper{ width:500px; height:500px; background: pink; margin:200px 500px; } .relative{ width: 100px; height:100px; position:relative; top:50px; left:50px; background: green; } </style> </head> <body> <div class="wrapper"> <div class="relative">relative</div> </div> </body> </html>
上面的是position定位流,除了position定位流,css還有float定位流,本來css發明這個屬性並非用來定位的,可是它確實在定位時很方便,css的float定位會發生高度坍塌,也就是當設置了float時,會使得本來的元素脫離原來的div,使用上面說的BFC就能夠解決這個問題,設置clear也能夠解決,具體看下面的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .wrapper{ background: pink; margin:200px 500px; border:1px solid #000; /*overflow:hidden;*/ } .clear{ clear:both; } .float{ width: 100px; height:100px; float:left; background: green; } </style> </head> <body> <div class="wrapper"> <div class="float">relative</div> //<div class="clear"></div> </div> </body> </html>
通過上面的基礎知識,對於css的盒子模型和定位機制有了比較好的理解,接下來,就能夠來檢驗一下,完成這幾種佈局需求:
1.2欄佈局:一遍定寬一遍自適應/一欄不定寬,一欄自適應/
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> body,div{padding: 0 ;margin-bottom: ;:20px;} .left,.right{height: 200px;} .left{float: left;width: 200px;background-color:skyblue;} .right{margin-left: 200px; background-color: greenyellow;} </style> </head> <body> <div class="left">left固定200px</div> <div class="right">right自適應</div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> body,div{padding: 0 ;margin:0;} .left,.right{height: 200px;padding: 10px;} .left{float: left;background-color:skyblue;} .right{overflow:hidden;background-color: yellow;} </style> </head> <body> <div class="left">left不固定</div> <div class="right">right自適應</div> </body> </html>
2.聖盃佈局:上中(左中右)下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .top{ width: 100%; height: 40px; background-color: #cccccc; } .footer{ width: 100%; height: 50px; background-color: #abdc44; } /*左右固定,中間自適應*/ /*Start*/ .container{ width: 100%; height: 100%; position: relative; } .left{ position: absolute; left: 0; top: 0; width: 400px; height: 600px; background-color: black; } .center{ width: auto; /*若是沒有這一句,那麼,center這個div的文字就不會自動換行*/ margin: 0 400px; height: 600px; background-color: yellow; } .right{ position: absolute; top: 0; right: 0; width: 400px; height: 600px; background-color: red; } /*End*/ </style> </head> <body> <div class="top">this is top</div> <div class="container"> <div class="left">this is left</div> <div class="center">this is center</div> <div class="right">this is right</div> </div> <div class="footer">this is footer</div> </body> </html>
3.高度自適應佈局:高度自適應
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> .container { width: 1200px; background: pink; overflow: hidden; } div.item { float:left; width:300px; padding-bottom: 5000000px; margin-bottom: -500000px; background: blue; border:1px solid #000; } </style> </head> <body> <div class="container"> <div class="item">aaa</div> <div class="item">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officia excepturi porro debitis quisquam corporis illum dolorum doloribus, similique esse veritatis harum hic, voluptatem veniam necessitatibus neque, animi, alias incidunt quasi!</div> <div class="item">sss</div> </div> </body> </html>
5.水平垂直居中定位:已知寬高/未知寬高
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> #father { width: 500px; height: 300px; background-color: skyblue; position: relative; } #son { width: 100px; height: 100px; background-color: green; position: absolute; left: 50%; top: 50%; margin-left: -50px; margin-top: -50px; } </style> </head> <body> <div id="father"> <div id="son">我是塊級元素</div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <style> #father { width: 500px; height: 300px; background-color: skyblue; position: relative; } #son { background-color: green; position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); } </style> </head> <body> <div id="father"> <div id="son">我是塊級元素</div> </div> </body> </html>
不知道你們實現剛纔的一系列的佈局是什麼感覺,個人感覺是累,那有沒有一種好用的佈局方式,不用去使用各類屬性來自我創造直接就能來用呢?flex佈局
Flex的基本概念就是容器和軸,容器包括外層的父容器和內層的子容器,父容器設爲flex後,它的全部子元素自動成爲容器成員
父容器屬性: flex-direction flex-wrap flex-flow justify-content align-items align-content 子容器屬性: order flex-grow flex-shrink flex-basis flex align-self
是的,它就是這麼簡單,接下來把上面的佈局實現一下,看它到底多方便
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>css3轉換</title> <style> .grid { display: flex; margin: 20px; } .grid-cell0 { border-radius:20px; width: 200px; height:180px; background:#eee; margin:10px; text-align:center; } .grid-cell1 { flex:1; border-radius:20px; width: 200px; height:180px; background:#eee; margin:10px; text-align:center; } .grid-cell2 { border-radius:20px; height:180px; background:#eee; margin:10px; text-align:center; } .grid-cell3 { flex:1; border-radius:20px; width: 200px; height:180px; background:#eee; margin:10px; text-align:center; } </style> </head> <body> <div class="grid"> <div class="grid-cell0">固定</div> <div class="grid-cell1">自適應</div> </div> <div class="grid"> <div class="grid-cell2">不固定</div> <div class="grid-cell3">自適應</div> </div> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>css3轉換</title> <style> * { margin: 0; padding: 0; text-align: center; } .holy-grid { display: flex; flex-direction: column; min-height: 100vh; /* 相對於視口的高度。視口被均分爲100單位的vh */ } header, footer { text-align: center; flex: 0 0 100px; height:100px; background: #aaa; } .holy-grid-content { display: flex; flex: 1; } .holy-grid-content-items { flex: 1; } .holy-grid-content-left { flex: 0 0 150px; background:blue; text-align: center; } .holy-grid-content-right { flex: 0 0 150px; background:pink; text-align: center; } </style> </head> <body class="holy-grid"> <header class="holy-grid-items">#header</header> <div class="holy-grid-content holy-grid-items"> <div class="holy-grid-content-items holy-grid-content-left"> # left </div> <div class="holy-grid-content-items holy-grid-content-center"> # center </div> <div class="holy-grid-content-items holy-grid-content-right"> # right </div> </div> <footer class="holy-grid-items">#footer</footer> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex 嵌套 之 高度自適應</title> <style media="screen"> body, html { height: 90%; } .flex { display: -webkit-flex; display: flex; flex-direction: column; } .item { flex: auto; } .overflow { overflow: auto; } .outer { height: 70%; border: 1px solid silver; } .contener { background: pink; border: 1px solid silver; } .contener>div{ padding: 5px; } </style> </head> <body> <h1>flex 嵌套佈局</h1> <div class="flex outer"> <div style="background-color: silver; padding: 10px;">外容器 自適應內容的區域 ... ...</div> <div class="flex item overflow" style="padding: 15px;"> <!-- 嵌套的item加flex樣式 及 overflow: auto屬性 --> <div class="flex contener overflow"> <!-- overflow: auto 高度自適應必須 --> <div style="background-color: yellow;"> <h3>內容器 - 頭部信息</h3> </div> <div class="item overflow"> <!-- overflow: auto 高度自適應必須 --> 內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br> 內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br> 內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br>內容溢出滾動部分 <br> </div> <div style="background-color: yellow;"> <h3>內容器 - 尾部信息</h3> </div> </div> </div> </div> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>css3轉換</title> <style> #father { width: 500px; height: 300px; background-color: skyblue; display: flex; justify-content: center; align-items: center; } #son { background-color: green; } </style> </head> <body> <div id="father"> <div id="son">我是塊級元素</div> </div> </body> </html>
除了上面的這些佈局,他還能實現均勻佈局,非均勻佈局
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>css3轉換</title> <style> .grid { display: flex; margin: 20px; } .grid-cell { flex: 1; border-radius:20px; height:180px; background:#eee; margin:10px; text-align:center; } </style> </head> <body> <div class="grid"> <div class="grid-cell">cell1</div> <div class="grid-cell">cell2</div> <div class="grid-cell">cell3</div> </div> <div class="grid"> <div class="grid-cell">cell1</div> <div class="grid-cell">cell2</div> </div> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>css3轉換</title> <style> .grid { display: flex; } .grid-cell,.cell-full,.cell-1of2,.cell-1of3 { border-radius:20px; height:180px; background:#eee; margin:10px; text-align:center; } .grid-cell { flex: 1; } .cell-full { flex: 0 0 100%; } .cell-1of2 { flex: 0 0 50%; } .cell-1of3 { flex: 0 0 33.3333%; } .cell-1of4 { flex: 0 0 25%; } </style> </head> <body> <div class="grid"> <div class="grid-cell cell-1of2">flex</div> <div class="grid-cell">flexxxxxx</div> <div class="grid-cell">sdfsdf</div> </div> <div class="grid"> <div class="grid-cell cell-1of3">flex</div> <div class="grid-cell">flexxxxxx</div> <div class="grid-cell">sdfsdf</div> </div> <div class="grid"> <div class="grid-cell cell-1of4">flex</div> <div class="grid-cell">flexxxxxx</div> <div class="grid-cell">sdfsdf</div> </div> </body> </html>
通過這個過程,終於找到了一種適合的佈局方法,這種方法適用於pc端和移動端,在移動端佈局的時候,會常常聽到rem佈局,這是什麼意思?要說明這個,還須要先來講說css中的單位,css常見的單位以下:
而後再來講說瀏覽器適配問題,經過百度流量統計研究院的數據可知,如今瀏覽器主流尺寸是:
在開發網頁時,針對PC端和移動端適配有2種方案
針對這些狀況,常見的移動端佈局有rem佈局
最後就來演示一下rem
function intiSize(){ //獲取當前瀏覽器窗口寬度(這裏的實質就是body寬度) var win_w=document.body.offsetWidth; //定義變量 var fontSize; if(win_w>640){ fontSize=24; } else{ //若是瀏覽器窗口寬度(這裏的實質就是body寬度)值小於320,取320 win_w=Math.max(320,win_w); fontSize=win_w/320*12 } //設置根元素的大小 document.getElementsByTagName('html')[0].style.fontSize=fontSize+'px';} //瀏覽器窗口寬度發生變化時條用這個函數,方便與改變窗口大小時候調試 onresize=intiSize;intiSize();
在上面動態的獲取了設備寬度,而後根據設計尺寸和設備尺寸的比例來設置了fontsize,這個意思就是1rem = win_w/320*12px,這樣在寫頁面的時候只要寫rem這個單位,自適應問題就迎刃而解了,這就是rem,一個相對尺寸
ok,css佈局完畢
本篇資料來源貼在下面,你們去看看:
行內盒子模型: https://biaoyansu.com/9.15
淺談margin負值: https://zhuanlan.zhihu.com/p/...
css單位: http://www.w3school.com.cn/cs...