這篇文章介紹了Flexbox模塊所有基本概念,而且是介紹Flexbox模塊的很好的一篇文章,所以這篇文章非常的長,你要有所準備。 學習Flexbox的曲線@Philip Roberts在Twitter上發(fā)了一個推: 學習Flexbox可不是件很有趣的事情,因為它將挑戰(zhàn)你所知道的CSS布局方面的知識。當然這也是非常正常的,因為一切知識都是值得學習的。 另外你要認值對待Flexbox。因為它是現(xiàn)代Web布局的主流方式之一,不會很快就消失。它也成為一個新的W3C標準規(guī)范。既然如此,那讓我們張開雙臂,開始擁抱它吧! 你將學習我將帶你先了解Flexbox的一些基礎(chǔ)知識。我想這是開始嘗試學習Flexbox的必經(jīng)階段。 學習基礎(chǔ)知識是件很有意思的事情,更有意思的是可以通過學習這些基礎(chǔ)理論知識,在實際的應(yīng)用程序中使用Flexbox。 我將帶您親歷很多“小知識點”之后,在文章末尾,使用Flexbox來做一個音樂應(yīng)用程序的布局(UI界面布局)。 看上去是不是棒棒的? 在開始進入學習Flexbox構(gòu)建音樂應(yīng)用程序的布局之前,你還將需要了解Flexbox在響應(yīng)式Web設(shè)計中所起的作用。 我將會把這一切都告訴你。 上圖是@Jona Dinges設(shè)計的。 在你開始構(gòu)建音樂應(yīng)用程序界面之前,我將一起陪你做一些練習。這看起來可能很無聊,但這是讓你徹底掌握Flexbox必經(jīng)的過程,只有這樣才能讓你很擅長的使用Flexbox。 說了這么多的廢話,那我們趕緊的開始吧?。y怪篇幅長,原來開始有這么的…(^_^)) 簡介CSS在過去的幾年里已發(fā)生了很大的變化。CSS中引入了設(shè)計師喜歡的filters、transitions和transforms等。但有些東西已經(jīng)消失了,可是我們都渴望這些東西能一直存在。 使用CSS制作智能的、靈活的頁面布局一直以來都是CSSer想要的,也有很人使用各種不同的CSS黑魔法去實現(xiàn)智能的頁面布局。 我們總是不得不忍受 似乎設(shè)計師和前端開發(fā)人員的這次祈禱終于被上帝聽到了。而且這一次,在很大的風格上做出了改變。 現(xiàn)在我們可以拋棄老司機們常用的CSS布局的黑魔法。也可以和 是時候去擁抱一個更簡潔的制作智能布局的現(xiàn)代語法。歡迎CSS Flexbox模塊的到來。 Flexbox是什么根據(jù)規(guī)范中的描述可知道,F(xiàn)lexbox模塊提供了一個有效的布局方式,即使不知道視窗大小或者未知元素情況之下都可以智能的,靈活的調(diào)整和分配元素和空間兩者之關(guān)的關(guān)系。簡單的理解,就是可以自動調(diào)整,計算元素在容器空間中的大小。 這樣聽起來是不是太官方了,其實我也明白這種感覺。 如何開始使用Flexbox這是每個人都會問的第一個問題,答案是比你預(yù)想的要簡單得多。 開始使用Flexbox時,你所要做的第一件事情就是聲明一個Flex容器(Flex Container)。 比如一個簡單的項目列表,我們常??吹降腍TML形式如下所示: <ul> <!--parent element--> <li></li> <!--first child element--> <li></li> <!--second child element--> <li></li> <!--third child element--> </ul> 一眼就能看出來,這就是一個無序列表( 你可以把 要開始使用Flexbox,必須先讓父元素變成一個Flex容器。 你可以在父元素中顯式的設(shè)置 實際是顯式聲明了Flex容器之后,一個Flexbox格式化上下文(Flexbox formatting context)就立即啟動了。 告訴你,它不是像你想像的那么復(fù)雜。 使用一個無序列表( /* 聲明父元素為flex容器 */ ul { display:flex; /*或者 inline-flex*/ } 給列表元素( li { width: 100px; height: 100px; background-color: #8cacea; margin: 8px; } 你將看到的效果如下圖所示: 你可能沒有注意到,但事實上已經(jīng)發(fā)生了變化?,F(xiàn)在已經(jīng)是一個Flexbox格式化上下文。 記住,默認情況下, 上面的圖是你希望的結(jié)果。 然而,簡單的寫一行代碼 現(xiàn)在列表元素( Flexbox模塊的開始,正如前面的介紹,在任何父元素上使用 你可能不明白為什么這一變化就能改變列表元素的排列方式。但我可以負責任的告訴你,你深入學習之后就能明白。現(xiàn)在你只需要信任就足夠了。 理解 還有一件事情,我需要提醒您注意。 一旦你顯式的設(shè)置了 這些術(shù)語會一次又一次的提到,我更希望你通過一些更有趣的東西來幫助你學習Flexbox模塊。 我使用了兩個關(guān)鍵詞,我們把重點放到他們身上。了解他們對于理解后面的知識至關(guān)重要。
這些只是Flexbox模塊的基礎(chǔ)。 Flex容器屬性flex-direction || flex-wrap || flex-flow || justify-content || align-items || align-content 通過上面的內(nèi)容,我們了解了一些基礎(chǔ)知識。知道了Flex容器和Flex項目是什么,以及如何啟動Flexbox模塊。 現(xiàn)在是一個好好利用它們的時間了。 有設(shè)置一個父元素作為一個Flex容器,幾個對齊屬性可以使用在Flex容器上。 正如你的塊元素的 好消息是,定義這些屬性不同于你以往使用過的任何一種方法。 flex-direction
它具有四個值: /* ul 是一個flex容器 */ ul { flex-direction: row || column || row-reverse || column-reverse; } 簡單點來說,就是 從技術(shù)上講,水平和垂直在Flex世界中不是什么方向(概念)。它們常常被稱為主軸(Main-Axis)和側(cè)軸(Cross-Axis)。默認設(shè)置如下所示。 通俗的說,感覺Main-Axis就是水平方向,從左到右,這也是默認方向。Cross-Axis是垂直方向,從上往下。 默認情況下, 盡管 如果把 flex-wrap
ul { flex-wrap: wrap || nowrap || wrap-reverse; } 我將通過一個例子來解釋如何使用 將Flex容器設(shè)置適合大小以適合放置更多的列表項目或者說讓列表項目換行排列。這兩種方式,你是怎么想的? <ul> <!--parent element--> <li></li> <!--first child element--> <li></li> <!--second child element--> <li></li> <!--third child element--> <li></li> <li></li> <li></li> </ul> 幸運的是,新添加的Flex項目剛好適合Flex容器大小。也就是Flex項目能剛好填充Flex容器。 再深入一點。 繼續(xù)給Flex容器內(nèi)添加Flex項目,比如說添加到 同樣的,F(xiàn)lex容器還是能容納所有的子元素(Flex項目)排列,即使瀏覽器出現(xiàn)了水平滾動條(當Flex容器中添加了很多個Flex項目,至使Flex容器的寬度大于視窗寬度)。 這是每一個Flex容器的默認行為。Flex容咕嚕會在一行內(nèi)容納所有的Flex項目。這是因為 ul { flex-wrap: nowrap; /*Flex容器內(nèi)的Flex項目不換行排列*/ }
當你希望Flex容器內(nèi)的Flex項目達到一定數(shù)量時,能換行排列。當Flex容器中沒有足夠的空間放置Flex項目(Flex項目默認寬度),那么Flex項目將會換行排列。把它( ul { flex-wrap: wrap; } 現(xiàn)在Flex項目在Flex容器中就會多行排列。 在這種情況下,當一行再不能包含所有列表項的默認寬度,他們就會多行排列。即使調(diào)整瀏覽器大小。 就是這樣子。注意:Flex項目現(xiàn)在顯示的寬度是他們的默認寬度。也沒有必要強迫一行有多少個Flex項目。 除此之外,還有一個值: 是的,你猜對了。它讓Flex項目在容器中多行排列,只是方向是反的。 flex-flow
你還記得使用 ul { flex-flow: row wrap; } 相當于: ul { flex-direction: row; flex-wrap: wrap; } 除了這個組合之外,你還可以嘗試一些其它的組合。 我相信你了解這些會產(chǎn)生什么樣的效果,要不嘗試一下。 justify-contentFlexbox模塊真得很好。如果你仍然不相信它的魅力,那么
ul { justify-content: flex-start || flex-end || center || space-between || space-around }
來看一個簡單的例子,還是考慮下面這個簡單的無序列表: <ul> <li>1</li> <li>2</li> <li>3</li> </ul> 添加一些基本樣式: ul { display:flex; border: 1px solid red; padding: 0; list-style: none; background-color: #e8e8e9; } li { background-color: #8cacea; width: 100px; height: 100px; margin: 8px; padding: 4px; } 你將看到的效果是這樣: 通過 可能會有以下幾種類型。 flex-start
ul { justify-content: flex-start; } flex-end
ul { justify-content: flex-end; } center和你預(yù)期的一樣, ul { justify-content: center; } space-between
ul { justify-content: space-between; } 你注意到有什么不同?看看下圖的描述: space-around最后, ul { justify-content: space-around; } 和 千萬不要覺得這些練習太多,這些練習可以幫助熟悉Flexbox屬性的語法。也能更好的幫助你更好的理解它們是如何影響Flex項目沿著Main-Axis的對齊方式。 align-items
ul { align-items: flex-start || flex-end || center || stretch || baseline } 它主要用來控制Flex項目在Cross-Axis對齊方式。這也是 下面是不同的值對Flex項目產(chǎn)生的影響。不要忘記這些屬性只對Cross-Axis軸有影響。 stretch
flex-start正如你所希望的 flex-end
center
baseline讓所有Flex項目在Cross-Axis上沿著他們自己的基線對齊。 結(jié)果看上去有點像 align-content還記得前面討論的
像 stretch使用 你看到的Flex項目間的間距,是Flex項目自身設(shè)置的 flex-start之前你看到過 flex-end
center你猜到了, 這是Flex容器的最后一個屬性。你現(xiàn)在知道如何使用各種Flex容器屬性。你可以在工作中實踐這些屬性。 Flex項目屬性order || flex-grow || flex-shrink || flex-basis 在前一節(jié)中,我解釋了Flex容器及其對齊屬性。 確實漂亮。我想你也找到了感覺?,F(xiàn)在我們把注意力從Flex容器轉(zhuǎn)移到Flex項目及其對齊屬性。 像Flex容器,對齊屬性也可以用在所有的Flex項目。那我們開始吧。 order允許Flex項目在一個Flex容器中重新排序?;旧?,你可以改變Flex項目的順序,從一個位置移動到另一個地方。 這不會影響源代碼。這也意味著Flex項目的位置在HTML源代碼中不需要改變。 值得注意的是,F(xiàn)lex項目會根據(jù) 要說明總得需要一個例子??紤]下面這個無序列表: <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> 默認情況下,所有Flex項目的 Flex項目顯示是按HTML源代碼中的順序來顯示,F(xiàn)lex項目 如果因為某些原因,在不改變HTML文檔源碼情況之下,想把Flex項目一從 <ul> <li>2</li> <li>3</li> <li>4</li> <li>1</li> </ul> 這個時候就需要 如果你以前使用過 li:nth-child(1){ order: 1; /*設(shè)置一個比0更大的值*/ } Flex項目就重新進行了排列,從低到高排列。不要忘記了,默認情況下,F(xiàn)lex項目2、3、4的 Flex項目2、3和4的 是的,你猜對了。它也增加堆棧?,F(xiàn)在代表Flex項目的最高的 當兩個Flex項目具有相同的 li:nth-child(1) { order: 1; } li:nth-child(3) { order: 1; } 現(xiàn)在仍是從低到高排列。這次Flex項目3排在Flex項目1后面,那是因為在HTML文檔中Flex項目3出現(xiàn)在Flex項目1后面。 如果兩個以下Flex項目有相同的 flex-grow 和 flex-shrinkFlex項目最優(yōu)秀的一點就是靈活性。
他們可能接受 接下來闡述它們的使用。使用一個簡單的無序列表做為例子,它只包含一個列表項。 <ul> <li>I am a simple list</li> </ul> ul { display: flex; } 添加更多的樣式,看起來像這樣: 默認情況下, 如果把 現(xiàn)在Flex項目擴展了,占據(jù)了Flex容器所有可用空間。也就是說開關(guān)打開了。如果你試著調(diào)整你瀏覽器的大小,F(xiàn)lex項目也會縮小,以適應(yīng)新的屏幕寬度。 為什么?默認情況下, 可以仔細看看 flex-basis記得前面我說過,F(xiàn)lex項目是當我沒有的。但我們也可以控制。
前面介紹的是非常生要的,所以我們需要花一點時間來加強對他們的理解。
注意:如果 這里同樣使用只有一個列表項的列表做為示例。 <ul> <li>I am a simple list</li> </ul> ul { display: flex } li { padding: 4px; /*some breathing space*/ } 默認情況,F(xiàn)lex項目的初始寬度由 這意味著,如果你增加Flex項目中的內(nèi)容,它可以自動調(diào)整大小。 <ul> <li>I am a simple list AND I am a simple list</li> </ul> 然而,如果你想將Flex項目設(shè)置一個固定的寬度,你也可以這樣做: li { flex-basis: 150px; } 現(xiàn)在Flex項目的寬度受到了限制,它的寬度是 它變得更加有趣。 flex速記
在適當?shù)臅r候,我建議你使用 li { flex: 0 1 auto; } 上面的代碼相當于: li { flex-grow: 0; flex-shrink: 1; flex-basis: auto; } 注意它們之間的順序。 如果 如果你只設(shè)置了 /* 這是一個絕對的Flex項目 */ li { flex: 1 1; /*flex-basis 默認值為 0*/ } /* 這是一個相對的Flex項目 */ li { flex-basis: 200px; /* 只設(shè)置了flex-basis的值 */ } 我知道你在想什么。你肯定想知道相對和絕對的Flex項目是什么?我將在后面回答這個問題。你只需要再次盲目信任就足夠了。 讓我們看看一些非常有用的 flex: 0 1 autoli { flex: 0 1 auto; } 這相當于寫了 很容易理解這一點,首先看看 明白了? 把注意力放到下一個屬性,
最后, 應(yīng)用到Flex項目效果就是這樣子: 注意:Flex項目沒有增長(寬度)。如果有必要,如果調(diào)整瀏覽器(調(diào)小瀏覽器寬度),F(xiàn)lex項目會自動計算寬度。 flex: 0 0 autoli { flex: 0 0 auto; } 這個相當于 還是老規(guī)矩:寬度是被自動計算,不過彈性項目不會伸展或者收縮(因為二者都被設(shè)置為零)。伸展和收縮開關(guān)都被關(guān)掉了。 它基本上是一個固定寬度的元素,其初始寬度是基于彈性項目中內(nèi)容大小。 看看這個 flex 簡寫是如何影響兩個彈性項目的。一個彈性項目會比另一個容納更多內(nèi)容。 應(yīng)該注意到的第一件事情是,這兩個彈性項目的寬度是不同的。因為寬度是基于內(nèi)容寬度而自動計算的,所以這是預(yù)料得到的。 試著縮放一下瀏覽器,你會注意到彈性項目不會收縮其寬度。它們從父元素中突出來了,要看到所有內(nèi)容,必須橫向滾動瀏覽器。 不要著急,稍后我會展示如何處理這種怪異的行為。 在縮放瀏覽器時,彈性項目不會收縮,而是從彈性容器中突出來了。 flex: 1 1 auto這與 還是按我前面立的規(guī)矩。即,自動計算初始化寬度,但是如果有必要,會伸展或者收縮以適應(yīng)整個可用寬度。 伸展和收縮開關(guān)打開了,寬度自動被計算。 此時,項目會填滿可用空間,在縮放瀏覽器時也會隨之收縮。 flex: “positive number”這里正數(shù)可以代表任何正數(shù)(沒有引號)。這與
li { flex: 2 1 0; / *與 flex: 2相同 */ } 與前面我立的規(guī)矩一樣,即,將彈性項目的初始寬度設(shè)置為零(嗯?沒有寬度?),伸展項目以填滿可用空間,并且最后只要有可能就收縮項目。 彈性項目沒有寬度,那么寬度該如何計算呢? 這個時候 當有多個彈性項目,并且其初始寬度 實際發(fā)生的是,彈性項目的寬度被根據(jù) 考慮如下兩個列表項標記及 CSS: <ul> <li>I am One</li> <li>I am Two</li> </ul> ul { display: flex; } /* 第一個彈性項目 */ li:nth-child(1) { flex: 2 1 0; /* 與寫成 flex: 2 相同*/ } /* 第二個彈性項目 */ li:nth-child(2){ flex: 1 1 0; background-color: #8cacea; } 記住設(shè)置 這里有兩個彈性項目。一個的 兩個項目上的伸展開關(guān)都打開了。不過,伸展度是不同的, 二者都會填滿可用空間,不過是按比例的。 它是這樣工作的:前一個占 知道是我怎么得到這結(jié)果的么? 是根據(jù)基本的數(shù)學比例?!眴雾棻壤?/ 總比例”,我希望你沒有漏過這些數(shù)學課。 看到出現(xiàn)啥情況了么? 即使兩個彈性項目內(nèi)容一樣大(近似),它們所占空間還是不同。寬度不是基于內(nèi)容的大小,而是伸展值。一個是另一個的約兩倍。
align-self
你已經(jīng)看到 如果想改變一個彈性項目沿著側(cè)軸的位置,而不影響相鄰的彈性項目,該怎么辦呢? 這是 該屬性的取值可以是這些值之一: li:first-of-type { align-self: auto || flex-start || flex-end || center || baseline || stretch } 這些值你已經(jīng)熟悉過了,不過作為回顧,如下是它們?nèi)绾斡绊懱囟繕隧椖?。這里是容器內(nèi)的第一個項目。目標彈性項目是紅色的。 flex-end
center
stretch
baseline
auto
在下面的情況下,彈性容器的 如下是上面Flex項目的基礎(chǔ)樣式。這樣你可以對發(fā)生的事情理解得更好點。 ul { display: flex; border: 1px solid red; padding: 0; list-style: none; justify-content: space-between; align-items: flex-start; /* 影響所有彈性項目 */ min-height: 50%; background-color: #e8e8e9; } li { width: 100px; background-color: #8cacea; margin: 8px; font-size: 2rem; } 現(xiàn)在你差不多已經(jīng)為有趣的部分做好準備了 絕對和相對Flex項目前面了解了一些基本概念,但重要的是要澄清一些重要的概念。那絕對和相對Flex項目之間到底有啥區(qū)別呢?二者之間主要的區(qū)別在于間距及如何計算間距。 一個相對Flex項目內(nèi)的間距是根據(jù)它的內(nèi)容大小來計算的。而在絕對Flex項目中,只根據(jù) 考慮如下的標記: <ul> <li> This is just some random text to buttress the point being explained. Some more random text to buttress the point being explained. </li> <li>This is just a shorter random text.</li> </ul> 兩個列表項元素,一個比另一個的文本多得多。 加點樣式: ul { display: flex; /*觸發(fā)彈性盒*/ } li { flex: auto; /*記住這與 flex: 1 1 auto; 相同*/ border: 2px solid red; margin: 2em; } 如下是結(jié)果: 如果你已經(jīng)忘了的話, Flex項目的初始寬度是被自動計算的( 當Flex項目因為被設(shè)置為 上面示例中Flex項目的內(nèi)容大小不相同。因此,F(xiàn)lex項目的大小就會不相等。 既然各個寬度開始就不是相等的(它是基于內(nèi)容的),那么當項目伸展時,寬度也保持不相等。 上面示例中的Flex項目是相對Flex項目。 下面我們把Flex項目變成絕對的, 就是說這次它們的寬度是基于 li { flex: 1 ; /*與 flex: 1 1 0 相同*/ } 效果如下: 這次看到兩個Flex項目的寬度相同了嗎? Flex項目的初始寬度是零( 這個之前就討論過了。現(xiàn)在寬度不會基于內(nèi)容大小而計算,而是基于指定的 絕對Flex項目的寬度只基于 Auto-margin 對齊當心Flex項目上的 你需要理解會發(fā)生什么。它會導致不可預(yù)料的結(jié)果,不過我打算解釋解釋。 當在Flex項目上使用 這玩意有點難理解。下面我來說明一下。 考慮如下的導航欄標記以及 CSS 樣式: <ul> <li>Branding</li> <li>Home</li> <li>Services</li> <li>About</li> <li>Contact</li> </ul> ul { display: flex; } li { flex: 0 0 auto; } 你可以看到如下的效果: 這里有幾件事情要注意:
現(xiàn)在在第一個列表項(branding)上使用 li:nth-child(1) { margin-right: auto; /*只應(yīng)用到右外邊距*/ } 剛剛發(fā)生了什么?之前的剩余空間現(xiàn)在已經(jīng)被分配到第一個Flex項目的右邊了。 還記得我前面說的話吧?當在Flex項目上使用 如果想讓一個Flex項目的兩邊都用自動外邊距對齊,該怎么辦呢? /* 如果愿意的話,也可以用 margin 簡寫來設(shè)置兩個邊 */ li:nth-child(1) { margin-left: auto; margin-right: auto } 現(xiàn)在空白被分配到Flex項目的兩邊了。 那么,這是不是對很酷的自動外邊距對齊的一種折衷方案呢?看起來是。如果沒注意的話,它也可能是受挫之源。當在一個Flex項目上使用自動外邊距( 例如,在上面的Flex容器上通過 ul { justify-content: flex-end; } Flexbox實戰(zhàn)導航系統(tǒng)是每個網(wǎng)站或者應(yīng)用程序的重要組成部分。這個世界上的每個網(wǎng)站都會有某種導航系統(tǒng)。 下面我們看看這些熱門網(wǎng)站,以及它們是如何實現(xiàn)其導航系統(tǒng)的。你看到Flexbox是如何幫助你更高效地創(chuàng)建這些布局嗎? 也仔細看看哪里會用得上自動外邊距特性。 Bootstrap導航AirBnB PC端導航Twitter PC端導航建議你自己寫代碼。試著自己實現(xiàn)這些導航系統(tǒng)。現(xiàn)在你已經(jīng)掌握了所需的所有知識。你所需要的是一點勇氣去開始寫。 下一節(jié)再見。但愿在你已經(jīng)完成了導航系統(tǒng)練習之后。 切換flex-direction會發(fā)生什么?提醒一下:將會有一些奇怪的東東出現(xiàn)。 在入手學習Flexbox時,這個部分是最惱火的。我估計很多彈性世界的新手也會發(fā)現(xiàn)如此。 還記得我說過默認的Main-Axis方向是從左到右,Cross-Axis方向是從上到下吧? 好吧,現(xiàn)在你也可以改變這個方向。 正如在較早的小節(jié)中所描述的那樣,用 當用 如果曾用英語寫過文字,那么你就知道英語是從左到右,從上到下來寫的。 Flexbox的默認Main-Axis和Cross-Axis也是采用同樣的方向。 不過,如果將 是的,日語。 如果你用日語寫過文字,那么應(yīng)該很熟悉了。(鄭重聲明,我從沒用過日語寫過文字)。 日文通常是從上到下寫的!沒那么怪,對吧? 這就解釋了為嘛這對英語寫作者可能有點惱火。 看看下面這個例子。標準無序列表( <ul> <li></li> <li></li> <li></li> </ul> ul { display: flex; flex-direction: column; } 如下是方向變化之前的樣子: 如下是方向變化之后的樣子: 出啥事了? 現(xiàn)在文字是以日語風格寫的:沿Main-Axis從上到下。 我很樂意指出,你會發(fā)現(xiàn)一些有趣的事情。 你會看到項目的寬度填滿了空間,對吧? 如果在之前要變成這樣子,得處理 下面來看看這些會如何影響新的布局。 li { flex-basis: 100px; } 下面是你會得到的。 什么?高度是被影響了,但是寬度沒有???我之前說過, 我是錯的,或者這樣說更好:我是用英語來思考。下面我們姑且切換到用日語思考。并且總是得有寬度。 在切換 方向已經(jīng)被切換了! 所以,即使你使用 這里再來一個例子。我發(fā)誓在這個例子之后你會有更好的理解。減少之前看到過的Flex項目的寬度,它們就不再填滿整個空間了: li { width: 200px; } 如果想把列表項移到屏幕中間該怎么辦呢? 在英語中,這是你到目前為止處理彈性容器的方式。就是說, 把Flex項目移到Main-Axis的中間 。 所以,你會用 再來看看: 所以請用日語文字來思考。Main-Axis是從上到下,你不需要這樣。Cross-Axis是從左到右。貌似是你所要的。 你需要 把Flex項目移到Cross-Axis的中間 。這里想起哪個Flex容器屬性了么? 是的, 所以要把這些項目移到中間,得這樣做: li { align-items: center; } 瞧瞧!Flex項目已經(jīng)居中了吧。 是有點懸乎,我知道。如果需要,就再復(fù)習一遍好了。在研究Flexbox時,我發(fā)現(xiàn)很多 CSS 書都略過了這一部分。 用日語文字來思考一下會有很大幫助。我們有必要了解,所有Flexbox屬性都是基于合適的 相信你又學到了一點新東西。我很開心解釋這些,希望你也很開心。 我的天啦,彈性盒解決了那問題了?很多設(shè)計師用 CSS 時遇到的一些典型問題已經(jīng)被Flexbox輕而易舉解決了。 @Philip Walton 在其 Flexbox解決了的問題這個項目 列出了 6 種典型的問題(到本文編寫時)。 他全面討論了之前用 CSS 的限制,以及目前Flexbox提供的解決方案。建議在完成本文后看一看。 在接下來的實踐環(huán)節(jié)中,在開始用彈性盒創(chuàng)建一個音樂應(yīng)用布局時,我會解釋他提出的一些概念。 Flex 不兼容瀏覽器的坑如果你不是在夢中寫 CSS 的那一類人的話,就可能想看看這個 Github 倉庫。 有些比我聰明的人在這里維護了一個Flexbox的 bug 列表及其變通方法。當有些事情沒有按預(yù)期起作用時,這是我看的第一個地方。我也會在后面的實踐環(huán)節(jié)中帶你踩踩一些顯眼的坑。
用彈性盒創(chuàng)建一個音樂應(yīng)用的布局在學習完了乏味嚴謹?shù)幕A(chǔ)知識之后,該有一些有趣的項目了。是時候玩玩實際的例子,并把剛獲得的Flexbox技能用上去。 想出一個好項目花了我好幾天。由于缺乏創(chuàng)造性的選擇,我想出了一個貓玩的音樂應(yīng)用布局。我稱它為 catty music 。 也許到了 2036 年,我們就能讓貓在火星上的某個地方唱搖滾。如下是完成了的布局看起來的樣子,并且完全是用Flexbox布局的。 可以在線上看,在這里。 如果在移動設(shè)備上看,外觀會稍微有點不同。這是在本文響應(yīng)式設(shè)計一節(jié)中要解決的問題。 不過,有件事我得坦白。我已經(jīng)做了許多人認為是錯誤的事情。我完全用Flexbox創(chuàng)建整個布局。 出于多種理由,這樣做可能并非那么理想。但是在這種情況下是故意的。我只是想用一個項目,向你展示所有可以用Flexbox做的事情。 如果你好奇什么時候使用Flexbox是對的,什么時候是錯的,那你可以讀讀我寫的一篇文章。
這里,我心里的石頭終于落地了?,F(xiàn)在我相信在讀完這個之后,沒人會對我大呼小叫了。 Catty Musci 中的一切都是用Flexbox布局, 這是故意盡可能地炫技。 所以下面我們開始把這個玩意建成!對于任何稍微合理一點的項目來說,有點規(guī)劃對避免效率低下是有幫助的。就讓我?guī)憧纯磩?chuàng)建 Catty Music 布局的規(guī)劃方法。 從哪里開始?只要用Flexbox創(chuàng)建布局,就應(yīng)該從找出布局中哪一個部分會作為Flex容器開始。然后才可以使用Flexbox提供的強大對齊屬性。 分析你可以讓整個包含體作為Flex容器(下圖中被包含在紅色邊框內(nèi)的部分),并把布局的其它部分分成Flex項目( 這樣做完全說得通,讓 你知道Flex項目也可以成為Flex容器嗎?是的,是可能的! 你想嵌套多深就嵌套多深(不過理智的做法是保持一個合理的水平)。于是,根據(jù)這個新啟示就有了這個…
你依然與我同在,對吧?像這樣拆分布局,會給你一個相當不錯的心理模型來處理。 在用Flexbox開始創(chuàng)建更為復(fù)雜的布局時,你會看到這有多重要。當然,你并不需要一個像上面那樣高大上的圖像。在紙上畫一個簡單的草圖就足夠了。 記得我說過可以想嵌套多深就嵌套多深吧?貌似這里還可以再來一個嵌套。 看看上面的主欄目( 可能你會決定不把主欄目( 是的,這樣做沒問題,因為 “Item 1a?—?A” 和 “Item 1a?—?B” 是垂直堆放的。 默認情況下, Flexbox中的 Flex 是指彈性、靈活。Flex容器默認是彈性的,跟響應(yīng)式有點類似。這也許是使用Flex容器,而不是普通 在你創(chuàng)建 Catty Music 時我會論及一些事情事情。你現(xiàn)在應(yīng)該去寫點代碼了。 HTML結(jié)構(gòu)從如下的基礎(chǔ) HTML 設(shè)置開始。 <!DOCTYPE html> <html> <head> <title>Catty Music</title> </head> <body> <main></main> <!--用來包含應(yīng)用的主欄目--> <footer></footer> <!--用來包含音樂控制按鈕和歌曲細節(jié)--> </body> </html> 然后為它設(shè)置樣式: html, body { height: 100%; /*顯式設(shè)置這,是很重要的*/ } body { display: flex; /*flex 超能力被激活了! */ flex-direction: column; /*垂直而不是水平堆放彈性項目(主欄目和腳注元素)*/ } 使用Flexbox的第一個步驟就是確定一個Flex容器。 這正好是上面代碼所做的。它將 Flex項目也被定義了( 注意,如果你對這個概念還是有點模糊,就應(yīng)該再看看我在之前開始分析時展示的圖像。 盯著最后的圖像,你應(yīng)該讓彈性項目工作起來。 讓腳注吸附在底部。讓放音樂控制的腳注吸附在頁面的底部,同時讓主欄目填滿剩余空間。 你怎么實現(xiàn)? main { flex: 1 0 auto; /*填滿剩余空間*/ } footer { flex: 0 0 90px; /*不會放大或者收縮 - 只會固定在 90px 高度。*/ } 請看上面列出的代碼中的注釋。多虧了 因為 在有些瀏覽器中,會有一個 bug,允許Flex項目收縮后比其內(nèi)容尺寸小。這是個很古怪的行為。 解決這個 bug 的變通方案是把 就像是說:請自動計算Flex項目的大小,但是不要收縮。有了這個簡寫值,就可以得到Flex項目的默認行為。 Flex項目會隨著瀏覽器縮放那個收縮??s放不是基于 這會導致Flex項目至少與它的寬度或者高度(如果聲明了)或者默認內(nèi)容尺寸一樣大。請不要忘記我在分析 現(xiàn)在事情匯集到一起了,下面我們放點樣式來定義間距和顏色。 body { display: flex; flex-direction: column; background-color: #fff; margin: 0; font-family: Lato, sans-serif; color: #222; font-size: 0.9em; } footer { flex: 0 0 90px; padding: 10px; color: #fff; background-color: rgba(61, 100, 158, .9); } 依然沒有啥奇跡。你將看到的效果如下圖所示: 看看事情是如何開始初具規(guī)模,你會讓它變得更好一點。 固定側(cè)邊欄如果你是跟著寫代碼,就更新一下你的 HTML 文檔。 <main> <aside> <!--這代表側(cè)邊欄,其中包含了來自 font-awesome 的圖標集--> <i class="fa fa-bars"></i> <i class="fa fa-home"></i> <i class="fa fa-search"></i> <i class="fa fa-volume-up"></i> <i class="fa fa-user"></i> <i class="fa fa-spotify"></i> <i class="fa fa-cog"></i> <i class="fa fa-soundcloud"></i> </aside> <section class="content"> <!--這一部分會容納除側(cè)邊欄以外的所有東西--> </section> </main> 上面的代碼列表已經(jīng)解釋的很清楚了。 至于圖標設(shè)置,我用了熱門的 Font Awesome 庫。這樣用你想要的圖標就簡單到只需添加一個 CSS 類即可。這就是我在 正如之前解釋過的,上面的 main { flex: 1 0 auto; /* 變成一個彈性項目*/ display: flex; /*只包含這一行,現(xiàn)在就有一個彈性容器,帶有彈性項目:側(cè)邊欄和主內(nèi)容區(qū)*/ } 很好,越來越有意思了,嘿嘿。 現(xiàn)在,主欄目是一個Flex容器了。下面我們來處理它的Flex項目之一,側(cè)邊欄。跟讓腳注吸附到頁面底部一樣,你還會想讓側(cè)邊欄吸附到頁面的左邊。 aside { flex: 0 0 40px; /*不會放大或者縮小。固定在 40px*/ } 側(cè)邊欄應(yīng)該讓圖標垂直堆放。可以讓側(cè)邊欄變成Flex容器,給它設(shè)一個 在下面的代碼列表中,看看你可能會怎么做。 aside { /* ... */ display: flex; /*現(xiàn)在也是一個彈性容器*/ flex-direction: column; /*垂直堆放圖標*/ /*因為方向改變了,如下在垂直方向上起作用。*/ justify-content: space-around; align-items: center; /*方向改變了!這條影響的是水平方向。將圖標居中*/ background-color: #f2f2f2; /*讓我變漂亮*/ } aside i.fa { font-size: 0.9em; /*圖標的字體大小*/ } 我已經(jīng)在上面的代碼中加了很多注釋,現(xiàn)在看看布局是如何漂亮。很干凈,只有幾行代碼。合情合理的代碼,沒有亂七八糟的招數(shù)。 主內(nèi)容區(qū)目前是空的。不要忘記它是第二個列表項,側(cè)邊欄是第一個。給這里放一下東西。給主內(nèi)容區(qū)添加內(nèi)容你可以再看看完工的項目,這樣就不會忘記接下來要發(fā)生的事情。 更重要的是,這能幫助你理解下面的代碼。更新 HTML 文檔,在 <section class="content"> <!--這一區(qū)是空的,用內(nèi)容填充它--> <div class="music-head"> <!--第一個列表項:包含音樂詳情--> <img src="images/cattyboard.jpg" /><!--專輯封面--> <section class="catty-music"> <!--專輯的其它細節(jié)--> <div> <p>CattyBoard Top 100 Single Charts (11.06.36)</p> <p>Unknown Artist</p> <p>2016 . Charts . 100 songs</p> </div> <div> <!--Music controls--> <i class="fa fa-play">Play all</i> <i class="fa fa-plus">Add to</i> <i class="fa fa-ellipsis-h">More</i> </div> </section> </div> <!--end .music-head--> <!--第二個列表項:包含專輯中的歌曲列表--> <ul class="music-list"> <li> <p>1. One Dance</p> <p>Crake feat CatKid & Cyla</p> <p>2:54</p> <p><span class="catty-cloud">CATTY CLOUD SYNC</span></p> </li> <li> <p>2. Panda</p> <p>Cattee</p> <p>4:06</p> <p><span class="catty-cloud">CATTY CLOUD SYNC</span></p> </li> <li> <p>3. Can't Stop the Feeling!</p> <p>Catin Cimberlake</p> <p>3:56</p> <p><span class="catty-cloud">CATTY CLOUD SYNC</span></p> </li> <li> <p>4. Work From Home</p> <p>Cat Harmony feat Colla</p> <p>3:34</p> <p><span class="catty-cloud">CATTY CLOUD SYNC</span></p> </li> </ul> </section> 嗯,我比上次添加了更多的東西,不過很簡單。我用一個 那么你打算如何設(shè)置樣式呢?看看我怎么做的? 首先,應(yīng)該讓 .content { display: flex; flex: 1 0 auto; /*這確保本區(qū)伸展到填滿可用空間*/ flex-direction: column; } 還應(yīng)該處理它的Flex項目: .music-head { flex: 0 0 280px; /*相同的備忘,不要伸展或收縮 - 固定為 280px*/ display: flex; padding: 40px; background-color: #4e4e4e; } .music-list { flex: 1 0 auto; list-style-type: none; padding: 5px 10px 0px; }
父元素已經(jīng)切換了 flex-direction。隨后需要讓它變成一個彈性容器,所以寫上 這依然沒讓人覺得有多漂亮,不過來吧,如果你還跟著,你做的很不錯了。贊一下。 這里有幾個問題。 歌曲列表看起來很糟糕包含音樂封面的部分有真的很難看的文本我會再次來你解決這些問題。 下面是我提出的解決方案。 處理歌曲列表每個歌曲列表包含 4 個段落,歌名、藝術(shù)家、時長和 “catty cloud sync”。 一定有辦法讓所有這些放在一行,每個段落占據(jù)該行相等空間。用Flexbox來搞定!這里的概念與很多柵格系統(tǒng)中用的一樣。 li { display: flex; /*段落現(xiàn)在顯示在一行上*/ padding: 0 20px; /*留點呼吸空間*/ min-height: 50px; } li p { flex: 0 0 25%; /*這是甜面醬*/ } 看到段落會發(fā)生什么了嗎? flex: 0 0 25%; “不要伸展或者收縮,不過每個段落應(yīng)該占據(jù) 使用這種技術(shù)這種技術(shù)是很有用的。可以用它來創(chuàng)建不相等的內(nèi)容區(qū)。比如,兩欄視圖。 一個欄目可以占可用空間的 .first-section: 0 0 60%; .second-section: 0 0 40%; 可以用這種技術(shù)創(chuàng)建柵格系統(tǒng)。你將看到的效果如下: 給列表交替的顏色,也處理一下 “catty cloud sync” 標簽。 li span.catty-cloud { border: 1px solid black; font-size: 0.6em; padding: 3px; } li:nth-child(2n) { background-color: #f2f2f2; } 所以,你征服它了,開始更好理解Flexbox方言了。這是你現(xiàn)在應(yīng)該得到的東西了。 現(xiàn)在要處理第二個問題了。讓相冊詳情文本看著更好看點。下面真是很簡單的事情。 .catty-music{ flex: 1 0 auto; display: flex; flex-direction: column; font-weight: 300; color: #fff; padding-left: 50px; } .catty-music div:nth-child(1){ margin-bottom: auto; } .catty-music div:nth-child(2){ margin-top: 0; } .catty-music div:nth-child(2) i.fa{ font-size: 0.9em; padding: 0 0.7em; font-weight: 300; } .catty-music div:nth-child(1) p:first-child{ font-size: 1.8em; margin: 0 0 10px; } .catty-music div:nth-child(1) p:not(:first-child){ font-size: 0.9em; margin: 2px 0; } 你做到了,而且做的相當不錯。 一個快速練習我留下腳注部分給你作為練習。試著自己解決腳注。只需采用相同的技術(shù)。你知道你能搞定嗎?如果卡住了,可以查看 Catty Music 的完整源代碼。你也可以把整個腳注分成Flex項目,從這里開始。 簡直不相信你到了這一步。下面,你會看到Flexbox是如何有助于響應(yīng)式設(shè)計。 Flexbox用于響應(yīng)式設(shè)計已經(jīng)有不少關(guān)于響應(yīng)式設(shè)計的書,有不少書還不錯。 因為本文專注于Flexbox,所以我不會深入響應(yīng)式設(shè)計。
像我之前在某處說過的那樣,用Flexbox,我們確實得到了一些開箱即用的響應(yīng)性。 Flexbox就像 彈性的盒子 。不過,可以通過媒體查詢搞定不同的屏幕尺寸,然后改變彈性行為。 如下是一個示例。我們又用簡單無序列表來幫忙。 <ul> <li>Home</li> <li>About</li> <li>Contact</li> <li>Register</li> <li>Login</li> </ul> 并且設(shè)置點樣式… ul { list-style-type: none; display: flex; border: 1px solid #4e4e4e; } li { flex: 0 0 auto; padding: 10px; margin: 10px; background-color: #8cacea; color: #fff; font-size: 1em; } 現(xiàn)在你已經(jīng)是Flexbox專家了,所以你知道是咋回事。 如下是導航欄的樣子。 這對于桌面以及平板電腦可能還挺酷,不過在某些屏幕尺寸上,就特別難看。在移動設(shè)備上,你會想讓導航條目垂直堆放。然后媒體查詢就登堂入室了。 @media screen and (max-width: 769px) { /* 這里的代碼只適用于寬度小于 769px 的屏幕設(shè)備*/ ul { flex-direction: column; /* 在更小的設(shè)備上,切換方向*/ } } 如果在這之前,你對響應(yīng)式設(shè)計還懂那么點,那就太棒了。把Flexbox納入你已有的知識好了。 順便說一句,我假設(shè)你理解媒體查詢是什么。如果不理解的話,看看下面的簡介。 媒體查詢媒體查詢是響應(yīng)式設(shè)計的核心,讓你可以以特定屏幕尺寸為目標,單獨指定運行在該設(shè)備上的代碼。 使用媒體查詢最流行的形式是 它看起來是這樣的: @media screen and (max-width: 300px) { /*在這個代碼塊中寫 CSS*/ } 看著這段代碼,猜都可以猜到它的作用。 “對于最大寬度為 在該代碼塊中的任何樣式都將適用于匹配表達式的設(shè)備,即 “ 我猜這有助于消除一些疑惑。 快速練習Catty music 在移動設(shè)備上的顯示有所不同。這可是個好消息。更棒的是你應(yīng)該試著重新創(chuàng)建它。 如果你遇到了難題,本教程代碼庫的鏈接在下一節(jié)。解決方案也在倉庫中??斓阶詈罅?!在總結(jié)部分,我將討論瀏覽器支持、有用的鏈接和幫助你上手的資源。 總結(jié)你已經(jīng)學習了如何使用Flex容器和Flex項目的對齊屬性。我引導你理解了絕對和相對彈性、自動外邊距對齊以及切換彈性方向。你還有機會將Flexbox技能應(yīng)用到創(chuàng)建 Catty Music 應(yīng)用,然后我也提到了響應(yīng)式設(shè)計。 這確實是一段漫長的旅程。 現(xiàn)在,我會向你解釋一些最終的概念。用一些我認為你會發(fā)現(xiàn)很有用的資源和鏈接幫助你。 Flexbox的瀏覽器支持這是當傾向于在生產(chǎn)中使用Flexbox時,被問到的一個常見的問題。這問題我也沒法很好回答,不過 caniuse 網(wǎng)站能很好處理這個問題。 如下是一個來自 caniuse 的屏幕截圖,瀏覽器支持很棒。你可以在這里自己看。 在我職業(yè)生涯早期,我瀏覽過 caniuse 很多次,依然沒法掌握表示的數(shù)據(jù)是什么意思。所以這里有一個簡單的解釋。 caniuse 網(wǎng)站的右下角是一個圖例。 看看上面的圖像,或者就訪問一下網(wǎng)站,找到圖例,就明白了。實際上就是這么回事。 |
|