跨瀏覽器的Flexbox:CSS Flexible盒模型3

來源:互聯網
上載者:User

文章簡介:CSS Flexible盒模型3又簡稱為Flexbox。摒棄我們傳統上使用的一些hack和組件,Flexbox給網路的發展帶來了很多正能量和興奮濟,讓我們一起把複雜的網站布局變得簡易和快速。

簡介

CSS Flexible盒模型3又簡稱為Flexbox。摒棄我們傳統上使用的一些hack和組件,Flexbox給網路的發展帶來了很多正能量和興奮濟,讓我們一起把複雜的網站布局變得簡易和快速。早前在Flexbox: fast track to layout nirvana?一文中介紹了Flexbox的一些基礎知識。在本文中,我將更進一步,借用Modernizr指令碼庫使用不同的樣式做Flexbox在各瀏覽器下做一些差異化處理,為Flexbox在各瀏覽器下提供最佳展示水平。

推出案例

在這篇文章中建立的例子,看起來如下圖所示:

圖片最終布局樣本。

這個樣本包含了多個伸縮容器(flexbox container)。如果你願意,可以點擊樣本查看,閱讀或探索更詳細的代碼。

整體布局

樣本網站的基本布局是這樣的:

<section>   <nav></nav>   <article></article>   <article></article> </section> 

<section>設定為一個伸縮容器,代碼如下所示:

section {   display: -ms-flexbox;   -ms-box-orient: horizontal;/*IE10中顯不一行,類似於flex-direction:row功能*/    display: -webkit-flex;   display: -moz-flex;   display: -ms-flex;   display: flex;      -webkit-flex-flow: row wrap;   -moz-flex-flow: row wrap;   -ms-flex-flow: row wrap;   flex-flow: row wrap; } 

註:從2011年到Opera和Chrome提供的最新規範,由於IE10目前支援不同的flexbox文法,在IE10中設定特定的屬性。Firefox和其他的webkit核心瀏覽器(如Safari)支援一個更舊版本的flexbox文法(2009),這使用flexbox更糟糕。除此之外,Modernizr報告IE10支援現代flexbox的文法,儘管它他還沒有用,因此我們需要使用老的文法來處理IE10下的flexbox效果,而不是使用Modernizr規則來做IE10的相容。詳細的可以看下文,你可以擷取更多的細節介紹。

讓他們都在同一水平流上,但<nav>使用下面的規則,迫使其在單獨的一行中顯示:

nav {   padding: 1rem;    -webkit-flex: 1 100%;   -moz-flex: 1 100%;   -ms-flex: 1 100%;   flex: 1 100%; } 

設定“flex-basis”為100%,使用其寬度和父容器的寬度一樣,同時迫使其他伸縮項目到新的一行。<article>的“flex-grow”的值設定如下:

article:nth-of-type(1) {   -webkit-flex: 2;   -moz-flex: 2;   -ms-flex: 2;   flex: 2; }  article:nth-of-type(2) {   -webkit-flex: 3;   -moz-flex: 3;   -ms-flex: 3;   flex: 3; } 

使他們在主軸點有一定比例的空間——第一個<article>佔40%,也就是寬度的五分之二;第二個<article>(也就是圖片容器)佔60%,也就是寬度的五分之三。這是值得記住——這個比例是只有在同一線上的伸縮項目具有,並非所有伸縮項目都具有的比例。

註:“flex-basis”是一個收縮基準值,首先用在伸縮項目上,在那之後主軸剩餘的空間會根據每個伸縮項目的“flex-grow”伸縮比率來劃分給每個伸縮項目,分配主軸的剩餘空間。當“flex-grow”沒有顯式的設定值時,它的預設值為“1”。為了更好的瞭解他是如何工作的原理,你可以閱讀flexbox模組中的flex部分,或者閱讀《Flexbox——快速布局神器》這篇文章裡面有關於flex的內容介紹。

伸縮項目

當你設定了一個元素為伸縮容器的時候,它只會影響他的子項目,而不會進一步的影響他的後代元素。但是沒有什麼可以阻止你為他們的後代設定為伸縮項目,使用一些布局變得複雜化。很簡單,在這裡,我把<nav>設定為伸縮容器,我可以讓他置中對齊,而且不必擔心容器的寬度或視窗的寬度大小。

nav {     display: -ms-flexbox;   -ms-box-orient: horizontal;   -ms-box-pack: center;/*ie10水平置中*/    display: -webkit-flex;   display: -moz-flex;   display: -ms-flex;   display: flex;      /*水平置中*/   -webkit-justify-content: center;   -moz-justify-content: center;   -ms-justify-content: center;   justify-content: center;  } 

接著再把<ul>設定為伸縮容器,保證他的子項目li能置中,代碼如下所示:

nav ul {   text-align: center;    display: -ms-flexbox;   -ms-box-orient: horizontal;   -ms-box-pack: center;    display: -webkit-flex;   display: -moz-flex;   display: -ms-flex;   display: flex;   -webkit-flex-flow: row wrap;   -moz-flex-flow: row wrap;   -ms-flex-flow: row wrap;   flex-flow: row wrap;   -webkit-justify-content: center;   -moz-justify-content: center;   -ms-justify-content: center;   justify-content: center;    width: 80%; }  nav a {   width: 100%; } 

我還添加了一些屬性來解決導覽功能表項的外觀。我希望<ul>不完全展開穿過螢幕,並且讓所有文本置中顯示,所以我設定了一個"width:80%"和"text-align:center"。同時給連結設定了寬度為100%,用來確保連結跨整個清單項目寬度。

接下來是神奇的時刻。在這一點上,清單項目看起來有眯重疊和奇怪,而用當他們開始封裝時看起來有點笨。沒有使用媒體查詢實現一個響應式的菜單,看上去很酷,那麼我們需要下面的代碼來實現:

nav ul li {   margin: 0 1.5rem;      -webkit-flex: auto;   -moz-flex: auto;   -ms-flex: auto;   flex: auto;      min-width: 5rem; } 

在這裡,我給清單項目設定了一個margin,讓他們有一定的空間,給他們設定了一個min-width,並且將"flex"設定為“auto”。這是flex的一個特殊的值,可以讓伸縮項目具有一個min-width的值,當沒有多餘的空間的時候,讓伸縮項目保持一個常數大小(min-width),但有多餘的空間時,伸縮項目能擴大填補。當你擴充和收縮頁面的時候看看會發生什嗎?

接下來設定第二個<article>,並設定裡面每個段落(包括段落裡的img):

article:nth-of-type(2) {   display: -ms-flexbox;   -ms-box-orient: horizontal;   -ms-box-pack: center;   -ms-box-align: center;    display: -webkit-flex;   display: -moz-flex;   display: -ms-flex;   display: inline-flex;      -webkit-flex-flow: row wrap;   -moz-flex-flow: row wrap;   -ms-flex-flow: row wrap;   flex-flow: row wrap;      -webkit-justify-content: center;   -moz-justify-content: center;   -ms-justify-content: center;   justify-content: center;      -webkit-align-items: center;   -moz-align-items: center;   -ms-align-items: center;   align-items: center;      -webkit-align-content: flex-start;   -moz-align-content: flex-start;   -ms-align-content: flex-start;   align-content: flex-start; }  article p {   margin: 0.5rem;      -webkit-flex: 1 20rem;   -moz-flex: 1 20rem;   -ms-flex: 1 20rem;   flex: 1 20rem; }   article p img {   display: block;   width: 100%;   border: 1px solid black; } 

在這裡給他們設定了個固定的flex-basis值,所以他們會根據每行的數量增加和減少自己的寬度(如下圖所示,沒有使用媒體查詢),並且會使用每一項,和每一項裡面的內容水平垂直置中顯示。

一個沒有媒體查詢的響應式映像框。

Flexbox反饋

支援Flexbox的瀏覽器有Webkite核心瀏覽器、Presto-based Opera、Firefox(即將),要真正支援主流瀏覽器將還需要一段時間。這意味著,如果我們想使用flxbox還需要選擇一些備案方法。2009年開始一些瀏覽器(老的webkit、firefox)支援老版的Flexbox文法。奇怪的是IE10從2011後既支援老的文法又支援新的文法。值得慶幸的是Modernizr指令碼庫使用“flexbox”和“flexbox-legacy”標記能檢測出Flexbox的現代文法和Flexbox舊的文法。實際上它並不支援這兩種——它支援一個介於這兩者之間的一種文法。這就是為什麼我們一直在IE10中把代碼寫在CSS中,而不是使用Modernizr代碼塊,你將在後面的文章介紹中可以看到。

註:截至2013年04月會,已經有討論如何處理Modernizr中Flexbox在IE10中檢測問題。

下面的表總結了Flexbox最新文法和2009年、2011年等效的混合文法:

上表顯示了不同的flexbox文法支援跨不同的瀏覽器,對不同屬性的等價物。

註:從2009年的規範"box-lines"屬性看上去等同於“flex-wrap”,但不幸的是,這個並不支援混合文法的瀏覽器。

所以,我在樣本中添加了以下代碼,用來實現支援flexbox混合寫法,但不支援flexbox的瀏覽器的flebox效果:

.no-flexbox section {   display: -webkit-box;   display: -moz-box;      -webkit-box-orient: horizontal;   -moz-box-orient: horizontal; }  .no-flexbox nav {   padding: 1rem;   width: 20%; }  .no-flexbox article {   -webkit-box-flex: 1;   -moz-box-flex: 1; }  .no-flexbox article p {   float: left; }  .no-flexbox article img {   display: block;   width: 200px; } 

然後在樣式中加入不支援flexbox,甚至不支援混合flexbox文法瀏覽器的相容樣式代碼:

.no-flexbox-legacy nav, .no-flexbox-legacy article {   float: left; }  .no-flexbox-legacy nav {   width: 20%; }  .no-flexbox-legacy article {   width: 36%; }  .no-flexbox article img {   float: left; } 

註:一個用來產生跨瀏覽器的flexbox代碼,並且可以幫你瞭解不同瀏覽器使用文法的線上工具Flexy Boxes。

Flexbox線上產生工具

在70+ 優秀的前端工具中收錄了類似於Flexy Boxes線上產生Flexbox的其他工具:

  1. Flexplorer
  2. CSS Flexbox Please!
  3. Flexiejs

——大漠

添加簡單的媒體查詢實現寬屏和窄屏的布局

最後,為瞭解決寬屏和窄屏下的布局,我決定添加幾個媒體查詢。但注意怎麼在媒體查詢中添加這些代碼,因為Flexbox天生就是建立響應式布局的神器。

首先在支援混合文法上寫一些代碼來解決響應式效果:

@media all and (max-width: 600px) {   h1 {     font-size: 5rem;   }      .no-flexbox section {      -webkit-box-orient: vertical;     -moz-box-orient: vertical;   }      .no-flexbox nav {     width: 100%;     margin-left: -3rem;   }      .no-flexbox nav a, .no-flexbox nav ul, .no-flexbox nav li {     width: 100%;   }  } 

接下來,一個現代flexbox修複,沒有在所有的瀏覽器,在小螢幕寬度。

@media all and (max-width: 480px) {   article:nth-of-type(1) {     -webkit-flex: 1 100%;     -moz-flex: 1 100%;     -ms-flex: 1 100%;     flex: 1 100%;   }      body {     min-width: 320px;   }      nav ul {     width: 100%;   }        .no-flexbox-legacy nav, .no-flexbox-legacy article {     float: none;   }    .no-flexbox-legacy nav, .no-flexbox-legacy article {     width: 100%;   } } 

最後用媒體查詢給大多少螢幕情況下設定一個置中效果:

@media all and (min-width: 1100px) {   section {     width: 1100px;     margin: 0 auto;   } } 
總結

此時是有限度的使用Flexbox,當都使用同一種方式支援現代瀏覽器的時候,Flexbox才會變得更加簡易。到現在為止,更有效果的支援,只是一些簡單的效果,單行的可以用flexbox,對於多行的在混合文法中就無法得到瀏覽器的支援。因為它的標準,我的樣本啟動並執行很正常,儘管混合文法的flexbox不如現代flexbox布局。另一個有趣的問題是,Firefox好像不支援置中,後來只好使用"margin: 0 auto"來實現(safari下支援置中)。

對於flexbox的一些簡單的使用,在現代瀏覽器(Chrome、Firefox、Safari、Opera Presto 12.1+,IE10+,IOS和Android)可以得到很好的支援。

譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了個人對技術的理解。如果翻譯有不對之處,還煩請同行朋友指點。謝謝!

如需轉載煩請註明出處:

英文原文:http://dev.opera.com/articles/view/advanced-cross-browser-flexbox



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.