前言
我們在手機上佈局一般是這個樣子的:
其中頭部對整個mobile的設計至關重要,而且坑也很多:
① 一般來說整個header是以fixed佈局,fixed這個產物在移動端來說本身坑就非常多
② 在Hybrid應用中,Header很多時候扮演了不一樣的角色,首先要完成以webview(window)為容器的功能,又要呼叫native提供的介面
Hybrid中Header的實現往往是一個難點,主要原因是同一套介面,要保證H5站點與native處於不一樣的環境呼叫相同的介面,完成不同的功能
③ 若是Hybrid中採用native提供的頭會導致mask不能全屏遮蓋,並且Header定製會變難;但是在Hybrid中採用H5提供的Header的話,萬一js報錯,便會導致毀滅性的假死,使用者除了關閉程式,就出不來了
PS:這裡以一個簡單的a標籤便可以解決js錯誤導致的假死問題,這裡與我們今天的內容無關,不予擴充套件
顯然,以上的內容與今天的文章沒有一毛錢關係,我們今天的主要內容是:
用float於Flexbox兩種方式實現我們的Header
小釵初學CSS有很多不足,理解也有錯誤,請您指正,並且感謝左盟主的指導
CSS3的佈局
CSS的佈局的演化
最初的佈局主要依賴於表格,表格主要的問題是:
① 不靈活
② 效率低,要整個渲染結束才會顯示
發展到CSS2.X系列,div+css的說法大行其道,很大程度上說,佈局對重構來說,變得比較簡單,但是由於塊級元素的特性,多列布局仍舊讓人很頭疼
div不能多列,span什麼的又不適合作為佈局元素,於是多列布局一般採用float實現,使用float就要清楚浮動
偶爾多列布局會使用定位屬性(事實上大範圍的佈局推薦定位元素),但是小範圍的絕對定位會不太靈活
CSS3中引入了一些新的佈局機制,顯然在PC瀏覽器中不適合,但幸運的是我是移動前端,所以不存在!!!
CSS3盒模型-box-sizing
盒模型的概念我這裡不再贅述,在瀏覽器中,元素都會被當做一個盒模型,CSS3中新增了一些概念對盒模型進行了補充
我們在實際工作中經常會出現這樣的程式碼,從而引起元素溢位,並導致橫向滾動條:
1 <div class="wrapper" style="width: 100px; border: 1px solid black;"> 2 <div style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px; background: gray;"> 3 </div> 4 </div>
因為對容器元素來說,他的高度只有100px(事實上他這裡還有2px的border,實際佔據102px)
所以說,即設定width,又設定margin等屬性,直接導致其真實width溢位了,但是塊級元素本身就是100%鋪開的,這裡不用設定
但是很多時候,我們又會設定,往往導致什麼橫向滾動條什麼的BUG,為了解決這個問題,CSS3提出了一個box-sizing特性
box-sizing: content-box | border-box
① content-box,為預設值,與CSS2.X保持一致
② border-box,此屬性的設定後,會表現與IE7表現一次,如果設定了width、margin等值,width會被重置,margin仍然會產生影響
PS:事實上,無論是事件冒泡還是IE盒模型,都是有其意義的
<div class="wrapper" style="width: 100px; border: 1px solid black;"> <div style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px; background: gray;box-sizing: border-box;"> </div> </div>
float佈局中的bfc
我們這裡以一個例子做說明,然後再逐步分析,我們現在來看一個簡單的頭部佈局
1 <html> 2 <head> 3 <meta charset="utf-8" /> 4 <title>Blade Demo</title> 5 <style type="text/css"> 6 .fl { float: left; } 7 .fr { float: right; } 8 .tc { text-align: center; } 9 span { display: inline-block; color: #099fde; } 10 </style> 11 </head> 12 <body> 13 <div class="header"> 14 <span class="fl">後退</span> <span class="fr">更多</span> <span class="fr">首頁</span> 15 <div class="tc"> 16 我是標題</div> 17 </div> 18 </body> 19 </html>
以上程式碼一個不同的地方是.tc的類,一個overflow一個沒有設定整個產生的結果是這樣的
http://sandbox.runjs.cn/show/pok0fp78
以上是一種header的常用佈局,但是為其中塊級元素設定overflow與否卻直接影響了tc的真實寬度,這其中的原因是什麼呢
前面我們說過了,在網頁中每個元素會表現得像一個盒子,不同的型別(display)會產生不同的結果
我們在js中一個物件會被其所在執行環境影響,或者說一個js物件不可能脫離其執行環境存在,整個元素對於瀏覽器而言事實上也是一個程式物件,他也有其依賴物件,這裡所謂的物件便是我們的格式化上下文
BFC為塊級格式化上下文,塊級元素的佈局會受其影響,他是一個獨立的渲染區,這又像一個沙箱,內部不會對外部進行汙染
並不是所有的塊級元素都會形成對應的格式化上下文,這裡與js一致,我們一般處於window環境下,有需要才會處於某個函式執行環境;當然,我們便有方法令某一個元素建立其獨立的環境
元素觸發(生成)BFC:
① 根元素本身便會建立BFC
② float不為none時
③ 定位元素,脫離文件流的元素
④ display為inline-block或者flex的元素(IE7模擬行內塊級元素的花招是zoom:1+inline)
⑤ overflow不為visible的元素
回到我們上面的例子,我們每一個span為inline-block漂浮元素,所以各自維護著獨立的BFC,那麼BFC佈局又有什麼規則呢,我這裡挑幾個關鍵的來說:
① BFC內部的元素會每行一個的排布,這裡參考塊級元素的佈局
② 元素間上下距離由margin決定,並且同一BFC中的元素會外邊距疊加
③ 每個元素的左邊(包含margin-left),與包含塊(padding內區域)的左邊框接觸,適用於float元素
④ BFC區域不會與浮動元素重疊,BFC內部的浮動元素會參與高度計算(很關鍵)
一般情況下我們的div為塊級元素,處於根元素的BFC下,所以其應該橫向鋪開,100%寬,正如上圖
但是設定overflow後,情況有所變化,div元素生成了獨立的BFC空間,整個佈局方式會發生變化
根據上述標準,BFC區域不與浮動元素BFC區域重疊,整個div所佔空間便被浮動元素擠壓,這是其寬度變化的原因
這裡是div觸發bfc與不觸發造成的區別,文字圍繞浮動元素便是最好的說明:
Flexbox簡介
簡單來說,支援情況各位不必關注,移動端支援的蠻好的,不必為那5%的份額做讓步,並且就現在國內手機的更新換代速度,用就好了。
Flexbox(伸縮佈局)的提出,為的是讓根元素中的子專案的寬度變化可以總是填充整個元素,換句話說子專案的佈局總能表現的很好:
① 不會溢位容器元素
② 不會換行
③ 專案多了,比較擠的時候會自動變小
比如這種場景:
木有申請的Flexbox,這個功能的實現是非常討厭的,而且就算resize神馬的,他都不會換行,正是居家必備良藥啊!
從這裡各位可能有所發現,Flexbox的表現,和表格有些相似,都不會溢位容器
容器與專案
現在display由多出了一個常用屬性:flex | inline-flex ;如前面所言,設定後會為容器建立獨立的格式化上下文,內中的佈局便特殊化了
容器的屬性包括:
① 伸縮流方向flex-direction,
① 伸縮流方向flex-direction,預設值為row
② 伸縮行換行flex-wrap,伸縮專案有時也會溢位容器,該屬性可設定專案是單行還是多行,預設不換
PS:容器還有一個flex-flow可同時設定上述屬性
③ ......
容器專案可設定屬性包括:
① 顯示順序
② 側軸對齊,一種是align-items,可以設定匿名專案與所有專案對齊保持一致,另一種是align-self用以為單獨專案上覆寫預設對齊,對於匿名專案align-self值與關聯的伸縮容器的align-items相同
③ 伸縮性,用以改變專案改變其高度或寬度添補可用的空間....
④ 伸縮行.....
PS:上面的介紹,我在用該知識點時候木有碰到,我也壓根就沒懂......
我這裡作為小白在實際使用中,用到比較關鍵的屬性是用於item專案的flex屬性,他決定專案的寬度,擴充套件比率,收縮比率
1 <style type="text/css"> 2 .flex { display: flex; } 3 4 </style> 5 <div class="flex"> 6 <div>專案一</div> 7 <div>專案二</div> 8 <div>專案三</div> 9 <div>專案四</div> 10 </div>
容器元素設定為flex後,內部上下問格式化物件被改變,所以內部佈局遵循flex規律,就算是塊級元素div也橫向排列了,這裡若是為其子元素設定flex屬性
.flex>div { flex: 1; }
那麼每個元素所佔區域便是一樣,真實善莫大焉啊!!!如果手動給專案二設定flex: 2,並且手動給專案三設定寬度,便會這樣
1 <div class="flex"> 2 <div>專案一</div> 3 <div style="flex: 2;">專案二</div> 4 <div style="min-width: 200px; max-width: 300px;">專案三</div> 5 <div>專案四</div> 6 </div>
這裡專案三的寬度被min-width定死了,直接影響了其它專案的寬度,但是無論如何,專案二的width都是其它基本專案的兩倍
PS:前段時間在三星一瀏覽器上flex:2被解析成了flex:0.5,我看著棒子的手機也是醉了
1 <html> 2 <head> 3 <meta charset="UTF-8"> 4 <meta name="google" value="notranslate"> 5 <title>CodePen - A Pen by ericlva</title> 6 <style> 7 * { margin: 0; padding: 0; } 8 ul { list-style: none; } 9 html, body { height: 100%; } 10 .font { width: 650px; margin: 10px auto; line-height: 20px; } 11 .mod { display: -webkit-flex; display: flex; width: 600px; margin: auto; text-align: center; } 12 .mod li:nth-of-type(1) { -webkit-flex: 1 1 200px; flex: 1 1 200px; background: red; } 13 .mod li:nth-of-type(2) { -webkit-flex: 1 2 300px; flex: 1 2 300px; background: green; } 14 .mod li:nth-of-type(3) { -webkit-flex: 1 3 500px; flex: 1 3 500px; background: yellow; } 15 </style> 16 </head> 17 <body> 18 <ul class="mod"> 19 <li>A</li> 20 <li>B</li> 21 <li>C</li> 22 </ul> 23 </body> 24 </html>
主軸總寬度600px,子元素設定了flex-basis,相加後200+300+500=1000px,子元素溢位400px
子元素設定了收縮因子,所以總寬度為:200*1+300*2+500*3=2300px;
子元素溢位量分別為:
A:200*1/2300=2/23,然後用2/23*400≈35
B:300*2/2300=6/23,然後用6/23*400≈104
C:500*3/2300=2/23,然後用15/23*400≈261
實際寬度減去溢位量,最後ABC寬度分別為:200-35=165, 300-104=196,500-261=239
補充:flex:flex-grow(擴充套件比率) flex-shrink(收縮比率) flex-basis(基準值)
PS:這裡感謝左盟主指導,CSS真難!!
前面的概念略複雜,不適合我這種初學者,這裡再做一個變形,將div專案的flex: 1去掉,似乎回到了第一個場景,但是我們做一點改變
1 <html> 2 <head> 3 <meta charset="utf-8" /> 4 <title>Blade Demo</title> 5 <style type="text/css"> 6 * { box-sizing: border-box; font-size: 12px; } 7 .flex { display: flex; } 8 .flex > div { width: 50px; height: 40px; } 9 </style> 10 </head> 11 <body> 12 <div class="flex"> 13 <div> 14 專案一</div> 15 <div > 16 專案二</div> 17 <div style="width: 100%;"> 18 專案三</div> 19 <div> 20 專案四</div> 21 </div> 22 </body> 23 </html>
以上是我對flex的粗淺認識,這些東西后面再補足吧。
Header佈局的實現
float實現佈局
Header一般是左中右佈局,右邊的專案不定,我這裡先以float實現
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>Blade Demo</title> 6 <style type="text/css"> 7 body, button, input, select, textarea { font: 400 14px/1.5 Arial, "Lucida Grande" ,Verdana, "Microsoft YaHei" ,hei; } 8 body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { margin: 0; padding: 0; } 9 body { background: #f5f5f5; } 10 ul, ol { list-style: none; } 11 h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: 500; } 12 h1 { font: 600 1.286em/2 Tahoma; } 13 h2 { font: 600 1.143em/2 Tahoma; } 14 h3 { font: 600 1em/1.5 Tahoma; } 15 address, cite, dfn, em, var, i { font-style: normal; font-weight: 400; } 16 17 body { padding: 10px; } 18 h1 { font-size: 18px; } 19 h1, h2, h3 { line-height: 2; font-weight: normal; } 20 .fl { float: left; } 21 .fr { float: right; } 22 .tc { text-align: center; } 23 24 .cui-header { height: 44px; line-height: 44px; background-color: #099fde; color: #fff; } 25 26 .cui-header > span { width: 44px; height: 44px; display: inline-block; } 27 .cui-header .cui-title { height: 44px; line-height: 44px; overflow: hidden; } 28 .cui-icon-more { display: inline-block; width: 30px; height: 30px; line-height: 26px; vertical-align: middle; text-align: center; } 29 .cui-icon-more::before { content: ""; display: inline-block; vertical-align: middle; width: 5px; height: 5px; border-radius: 5px; background-color: #fff; box-shadow: 10px 0 #fff, -10px 0 #fff; } 30 </style> 31 </head> 32 <body> 33 <header class="cui-header"> 34 <span class="cui-back fl tc">返回</span> 35 <span class="cui-more fr tc"><i class="cui-icon-more"></i></span> 36 <span class="cui-home fr tc">home</span> 37 <h1 class="cui-title tc"> 38 標題</h1> 39 </header> 40 </body> 41 </html>
http://sandbox.runjs.cn/show/vpbscpn4
然後再以flex做實現
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>Blade Demo</title> 6 <style type="text/css"> 7 *:not(img), *:before, *:after { box-sizing: border-box; } 8 body, button, input, select, textarea { font: 400 14px/1.5 Arial, "Lucida Grande" ,Verdana, "Microsoft YaHei" ,hei; } 9 body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { margin: 0; padding: 0; } 10 body { background: #f5f5f5; } 11 ul, ol { list-style: none; } 12 h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: 500; } 13 h1 { font: 600 1.286em/2 Tahoma; } 14 h2 { font: 600 1.143em/2 Tahoma; } 15 h3 { font: 600 1em/1.5 Tahoma; } 16 address, cite, dfn, em, var, i { font-style: normal; font-weight: 400; } 17 18 body { padding: 10px; } 19 h1 { font-size: 18px; } 20 h1, h2, h3 { line-height: 2; font-weight: normal; } 21 .fl { float: left; } 22 .fr { float: right; } 23 .tc { text-align: center; } 24 25 .cui-header { height: 44px; line-height: 44px; background-color: #099fde; color: #fff; display: flex; align-items: center; } 26 27 .cui-header > span { width: 45px; height: 45px; } 28 .cui-header .cui-title { height: 44px; line-height: 44px; overflow: hidden; width: 100%; } 29 .cui-icon-more { display: inline-block; width: 30px; height: 30px; line-height: 26px; vertical-align: middle; text-align: center; } 30 .cui-icon-more::before { content: ""; display: inline-block; vertical-align: middle; width: 5px; height: 5px; border-radius: 5px; background-color: #fff; box-shadow: 10px 0 #fff, -10px 0 #fff; } 31 </style> 32 </head> 33 <body> 34 <header class="cui-header"> 35 <span class="cui-back tc">返回</span> 36 <h1 class="cui-title tc"> 37 標題</h1> 38 <span class="cui-home tc">home</span> 39 <span class="cui-more tc"><i class="cui-icon-more"></i></span> 40 41 </header> 42 </body> 43 </html>
http://sandbox.runjs.cn/show/ummvcxx5
這裡我們以float以及flex實現了Header的基本佈局,但是在flex的情況下,我們感覺span元素有點擠,因為他沒有45px,事實上他只有32px
這個便是由於我們前面的各種偏移導致,具體導致的原因,我這裡也在摸索,這裡暫時不予討論了,後面再專門放一個flex的學習部落格
Header js的實現
事實上Header的應用與結構不止如此簡單,關於其js實現,我們後面點說吧,待續......
結語
我們今天對Header的佈局做了一些學習,因為小釵初學css,文中有不足請您提出,希望對各位有幫助