天天看點

【HTML5&CSS3進階學習02】Header的實作·CSS中的布局

前言

我們在手機上布局一般是這個樣子的:

其中頭部對整個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,我看着棒子的手機也是醉了

 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去掉,似乎回到了第一個場景,但是我們做一點改變

 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實作

 View Code

http://sandbox.runjs.cn/show/vpbscpn4

然後再以flex做實作

http://sandbox.runjs.cn/show/ummvcxx5

這裡我們以float以及flex實作了Header的基本布局,但是在flex的情況下,我們感覺span元素有點擠,因為他沒有45px,事實上他隻有32px

這個便是由于我們前面的各種偏移導緻,具體導緻的原因,我這裡也在摸索,這裡暫時不予讨論了,後面再專門放一個flex的學習部落格

Header js的實作

事實上Header的應用與結構不止如此簡單,關于其js實作,我們後面點說吧,待續......

結語

我們今天對Header的布局做了一些學習,因為小钗初學css,文中有不足請您提出,希望對各位有幫助

本文轉自葉小钗部落格園部落格,原文連結:http://www.cnblogs.com/yexiaochai/p/4074624.html,如需轉載請自行聯系原作者

繼續閱讀