五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > CSS Grid和Flexbox實際的布局用法和區(qū)別

CSS Grid和Flexbox實際的布局用法和區(qū)別

文章來源:365jz.com     點擊數(shù):463    更新時間:2018-06-11 11:25   參與評論

Grid布局方式借鑒了平面裝幀設(shè)計中的格線系統(tǒng),將格線運用在屏幕上,而不再是單一的靜態(tài)頁面,可以稱之為真正的柵格。本文將詳細介紹grid布局

引入

  對于Web開發(fā)者來說,網(wǎng)頁布局一直是個比較重要的問題。但實際上,在網(wǎng)頁開發(fā)很長的一段時間當(dāng)中,我們甚至沒有一個比較完整的布局模塊。總的來說 Web 布局經(jīng)歷了以下四個階段:

  1、table表格布局,通過 Dreamweaver 拖拽表格或者手寫 table 標(biāo)簽布局

  2、float浮動及position定位布局,借助元素元素盒模型本身的特性以及 float position 等屬性等進行布局

  3、flex彈性盒模型布局,革命性的突破,解決傳統(tǒng)布局方案上的三大痛點 排列方向、對齊方式,自適應(yīng)尺寸。是目前最為成熟和強大的布局方案

  4、grid柵格布局,二維布局模塊,具有強大的內(nèi)容尺寸和定位能力,適合需要在兩個維度上對齊內(nèi)容的布局

  Grid Layout 是一種基于二維網(wǎng)格的布局系統(tǒng),旨在完全改變我們設(shè)計基于網(wǎng)格的用戶界面的方式,彌補網(wǎng)頁開發(fā)在二維布局能力上的缺陷

  與flex分為伸縮容器和伸縮項目類似,grid也分為網(wǎng)格容器和網(wǎng)格項目

 

網(wǎng)格容器

display


  通過display屬性設(shè)置屬性值為grid或inline-grid可以創(chuàng)建一個網(wǎng)格容器。網(wǎng)格容器中的所有子元素就會自動變成網(wǎng)格項目(grid item)

display: grid
display: inline-grid

  網(wǎng)格項目默認(rèn)放在行中,并且跨網(wǎng)格容器的全寬

 

顯式網(wǎng)格


  使用grid-template-columns和grid-template-rows屬性可以顯式的設(shè)置一個網(wǎng)格的列和行 

【grid-template-rows】

  默認(rèn)值為none

  grid-template-rows指定的每個值可以創(chuàng)建每行的高度。行的高度可以是任何非負值,長度可以是px、%、em等長度單位的值

grid-template-rows: 60px 40px

  item1和item2具有固定的高,分別為60px和40px。因為只定義了兩個行的高度值,所以item3和item4的高度是根據(jù)其自身的內(nèi)容來定義。


【grid-template-columns】

  默認(rèn)值為none

  像行一樣,通過grid-template-columns指定的每個值來創(chuàng)建每列的列寬

grid-template-columns: 40px 50px 60px

  item4和item5放置在新的一行(第二行),因為grid-template-columns只定義了三列的大小,它們也分別放置在列1、列2和列3;其中列1、列2和列3的尺寸大小等于item1、item2和item3寬度。item1、item2和item3具有固定的寬度值,分別為40px、50px和60px



在深入介紹Flexbox和Grid結(jié)合優(yōu)勢之前,先來看看這樣的一個需求。需要做一個響應(yīng)式設(shè)計,這個設(shè)計效果看起來復(fù)雜,在不同的視窗中,改變順序和布局的效果。這個設(shè)計效果看起來復(fù)雜,但用CSS的Grid和Flexbox來實現(xiàn)這樣的布局,就會顯得容易多了。

先來看我們需要的設(shè)計風(fēng)格:

上面的是設(shè)計草圖。從草圖上可以看出,不管是什么樣的屏幕下,整個Card有四個區(qū)域:A、B、C和D。那么我們就很容易借助Grid來構(gòu)建這幾個區(qū)域了。

構(gòu)建CSS Grid

從上面的草圖我們可以看出,我們可以把整個卡片分成四個區(qū)域。如下圖:

如果你接觸過CSS的Grid,你肯定知道,有一些屬性是瀏覽器還不支持的。不過這里咱們不糾結(jié)這一部分,在這個示例中,使用瀏覽器已支持的屬性。那么回到示例中來,我們整個Card分為四個區(qū)域。那么對應(yīng)的HTML中,我們也是使用四個區(qū)域:

<div class="card">
    <div class="grid-area grid-area_a">A區(qū)</div>
    <div class="grid-area grid-area_b">B區(qū)</div>
    <div class="grid-area grid-area_c">C區(qū)</div>
    <div class="grid-area grid-area_d">D區(qū)</div></div>

你可以具體化每個區(qū)域。但暫時我們不處理每個區(qū)域內(nèi)部內(nèi)容。

移動端優(yōu)先

了解響應(yīng)式布局的同學(xué)都應(yīng)該知道,在響應(yīng)式布局中,遵循的原則是移動端先行。那咱們先實現(xiàn)移動端的布局。

這是一個非常簡單的網(wǎng)格布局。我們可以使用CSS的Grid來實現(xiàn):

.card {    display: grid;
    grid-template-rows: repeat(3, min-content);
    grid-template-columns: 33% calc(67% - 55px) 55px;
    grid-auto-rows: min-content;}.grid-area_a {    grid-row: 1 / span 2;
    grid-column: 1;
    background-color: green;}.grid-area_b {    grid-row: 1;
    grid-column: 2 / span 2;
    background-color: orange;}.grid-area_c {    grid-row: 2;
    grid-column: 2 / span 2;
    background-color: lime;}.grid-area_d {    grid-row: 3;
    grid-column: 1 / span 3;
    background-color: yellow;}

通過Firefox瀏覽器網(wǎng)格調(diào)試工具,我們可以看很清楚的看出我們的網(wǎng)格分布圖:

再給.card添加一下基本樣式:

.card {    max-width: 300px;
    position: relative;
    padding: 15px 10px;
    background-color: gray;}

可以看到的效果如下:

上面看到的效果僅是幾個區(qū)域的布局效果。我們接下來給里面添加內(nèi)容,并加上對應(yīng)的效果,看到的卡片效果如下:

上面的草圖對于移動端還有第二種風(fēng)格。

.card {    display: grid;
    grid-template-rows: repeat(3, min-content);
    grid-template-columns: 33% calc(67% - 95px) 95px;
    grid-auto-rows: min-content;}.grid-area_a {    grid-row: 1 / span 3;
    grid-column: 1;}.grid-area_b {    grid-column: 2;}.grid-area_c {    grid-row: 2;
    grid-column: 2;}.grid-area_d {    grid-row: 1 / span 3;
    grid-column: 3;    }

PC端布局

移動端先行,上面我們實現(xiàn)了兩種移動端的布局。接下來處理PC端,也就是桌面端。這個我們通過媒體查詢來處理。

@media only screen and (min-width: 768px) {    .card {        grid-template-rows: repeat(4, min-content);
        grid-template-columns: 100%;
    }

    .grid-area {        grid-column: 1;
    }

    .grid-area_a {        grid-row: 1;
    }

    .grid-area_b {        grid-row: 2;
    }

    .grid-area_c {        grid-row: 3;
    }

    .grid-area_d {        grid-row: 4;
    }

    .grid-area_d {        flex-direction: row;
    }}

效果如下:

多卡片

上面看到的效果,我們只是一張卡片。如果我們有N張卡片呢?首先我們在HTML中復(fù)制一下.card的結(jié)構(gòu)。讓我們的頁面具有N張卡片。

同樣是移動端先行。代碼稍做調(diào)整:

.card {    max-width: calc(100vw - 10px);}body {    display: grid;
    grid-auto-rows: min-content;}@media only screen and (min-width: 768px) {    body {        grid-template-columns: repeat(4, auto);
    }
    .card {        max-width: 400px;
        grid-template-rows: repeat(4, min-content);
        grid-template-columns: 100%;
        margin: 5px;
    }
    ...
}

拖動你的瀏覽器,可以看到的效果如下:

2017年3月,CSS Grid在幾個星期內(nèi)就被發(fā)送到Chrome、Firefox和Safari的生產(chǎn)版本中。很高興,大家可以使用它來解決實際問題。

CSS Grid是一種不同的布局方式,在大家開始使用規(guī)范的時候,有很多常見的問題。這篇文章的目的是回答其中的一些問題,并且將會是Smashing Magazine中有關(guān)于CSS Grid一系列文章中的一篇。

為什么使用CSS Grid而不是CSS Flexbox?

在CSS網(wǎng)格布局在瀏覽器中可用之前,很多人都認(rèn)為Flexbox是我們所有設(shè)計相關(guān)問題的答案。然而,F(xiàn)lexbox并沒有提供比浮動更好的網(wǎng)格系統(tǒng),盡管它確實比浮動創(chuàng)建一個網(wǎng)格系統(tǒng)更簡單。一個真正的網(wǎng)格是二維的。這兩個維度就是行和列,并且使用網(wǎng)格布局,你可以同時控制它們。使用Flexbox,你可以選擇是否將這些項列成一行或列,一個或另一個,而不是兩個。

這里有一個簡單的示例,突出其區(qū)別。第一個布局使用Flexbox,為了能盡可能多的使用盒子,以適合可用的寬度。這里我們控制了整個行中的布局。允許Flex項目進行包裹,因此會創(chuàng)建新的行,但是每一行都是一個新的Flex容器??臻g分布在行中發(fā)生,所以取決于最后一行多少項,它們有時不會與上面的Flex項對齊。

第二個示例使用CSS Grid實現(xiàn)相同的布局,但是,你可以看到,最后一行中的項目始終保持在它們的列中。這是因為在網(wǎng)格中,我們將項目排列成行和列 —— 二維布局。

你還可以在第二個示例中看到,在CSS Grid布局中,我們不需要向網(wǎng)格添加任何內(nèi)容來進行布局。所有東西都被放在容器上。在Flexbox布局中,你必須針對Flex項目來設(shè)置flex-grow、flex-shrink和flex-basis屬性。這是理解網(wǎng)格布局關(guān)鍵所在,也可能是大家有很多困惑的地方。Grid主要是關(guān)于包含元素的,而我們之前的所有布局方法都依賴于我們在布局中設(shè)置的寬度,使某些東西看起來像一個網(wǎng)格。

如果你使用一個簡化版本的浮動12列“網(wǎng)格”,我們必須計算每一列的百分比大小,加上每個列之間間距的百分比大小。要創(chuàng)建跨多個列的項,需要將所有項的寬度加上用于分隔它們的邊界寬度。

使用Flexbox創(chuàng)建的網(wǎng)格也是如此。當(dāng)我們在父節(jié)點上通過display:flex創(chuàng)建Flex布局時,F(xiàn)lex所有的大小都需要在單個Flex項目上進行。為了制作一個Flexbox的“網(wǎng)格”,我們必須阻止Flexbox做靈活的操作,而是應(yīng)該設(shè)置百分比寬度,就像我們前面的浮動網(wǎng)格示例一樣。使用Flexbox要比浮動更有一些優(yōu)勢,比如控制對齊和列等高之類的要簡易得多。然而,在Flexbox和浮動的方法中仍然沒有網(wǎng)格,只是通過設(shè)置項目的大小,并將它們排列起來,讓其看起來像網(wǎng)格的東西。

在網(wǎng)格中,所有的大小都發(fā)生在容器上。一旦我們創(chuàng)建了我們的網(wǎng)格軌道,我們就可以告訴單個項目(Grid項目)有多少個軌道可以跨越,但我們卻有一個實際的網(wǎng)格。我們可以完全拋棄行的容器,因為網(wǎng)格已經(jīng)有行了。這也意味著,我們也可以使用相同的方式進行跨列。這對于以前而言是件很難做的事情。

是否應(yīng)該將網(wǎng)格用于主布局和Flexbox用于組件布局

隨著大家開始接觸和學(xué)習(xí)CSS Grid的布局,這個神話不斷涌現(xiàn)。也許它來自于網(wǎng)格系統(tǒng)的使用,比如在Bootstrap或Foundation,大家關(guān)心的是一個整體網(wǎng)格上放置項目。這當(dāng)然是使用網(wǎng)格布局的一種方法。不過,我還是會考慮在上一節(jié)提到的不同之處。問問你自己,這個布局是一維的還是二維的?

如果你可以使用你的組件,并且用行和列在它的上面繪制一個網(wǎng)格。它是二維的,那就使用CSS Grid來布局。

如果相反,你希望單個項目在一行中進行擴展,而不考慮上面一行中發(fā)生的情況,那就應(yīng)該使用Flexbox布局更為合適。

不管你想要展示的是一個完整的頁面,還是一個很小的組件。重要的是你想在布局里面的項目分配空間和相互關(guān)聯(lián)。

網(wǎng)格軌道大小是否由內(nèi)容來決定?

我們已經(jīng)看到了如何在使用網(wǎng)格布局時,在容器上設(shè)置網(wǎng)格和網(wǎng)格大小。但是,網(wǎng)格中的項可以指定網(wǎng)格軌道大小。這里要記住的關(guān)鍵是,一個單元格大小的改變將會改變整個軌道的大小。如果你不希望這種情況發(fā)生,你可能需要一個單一維度的Flexbox布局。

最簡單的方法就是使用auto,因為它會默認(rèn)在隱式網(wǎng)格中創(chuàng)建網(wǎng)格軌道。一個自動大小的網(wǎng)格軌道將擴展到包含所有的內(nèi)容。在下面的示例中,我有一個兩列布局,在右邊的列中添加更多的內(nèi)容會導(dǎo)致整個行的擴展。第二行也是自動大小,再擴展以包含內(nèi)容。

我們可以使用兩個參數(shù)來控制網(wǎng)格軌道大小,例如創(chuàng)建一個最小的網(wǎng)格軌道,但其仍然會增長以適應(yīng)較大的網(wǎng)格項目。我們可以使用minmax()函數(shù)來做這個。傳給minmax()函數(shù)的第一個值,它是網(wǎng)格軌道最小的值,第二個值是網(wǎng)格軌道最大的值。因此,你可以設(shè)置200px的行,但通過auto設(shè)置為網(wǎng)格軌道最大值,那么當(dāng)有較多的內(nèi)容時,不會出現(xiàn)內(nèi)容溢出。

也有一些有趣的關(guān)鍵詞可以設(shè)置大小,將在以后的文章中對它們進行適當(dāng)?shù)年U述。這些關(guān)鍵詞在指定網(wǎng)格中允許內(nèi)容來改變網(wǎng)格軌道大小,并且可以在CSS內(nèi)部和外部的大小模塊(CSS Intrinsic and Extrinsic Sizing Module)中找到相關(guān)的詳細內(nèi)容。例如min-content關(guān)鍵詞的示例,使用它創(chuàng)建一個網(wǎng)格軌道時,將會創(chuàng)建盡可能小的網(wǎng)格軌道。

在我的例子中,這個詞意味著其成為最寬的東西,網(wǎng)格軌首縮小以適應(yīng)它。

相反,如果你使用的是max-content,你會得到一個盡可能大的網(wǎng)格軌道。這可能會導(dǎo)致溢出情況,在下面的示例中,使用了overflow: scroll設(shè)置了網(wǎng)格溢出,所以max-content的網(wǎng)格軌道會導(dǎo)致滾動條出現(xiàn)。

關(guān)鍵要記住的是,這將會發(fā)生在整個網(wǎng)格軌道上。你需要確保網(wǎng)格軌道的其他網(wǎng)格項目也能巧妙地吸收額外的空間。

了解了如何對網(wǎng)格軌道大小進行調(diào)整,以及內(nèi)容將如何改變網(wǎng)格軌道大小,這可能是新手使用CSS Grid布局中會感到最為困惑的事情之一。這需要花一點時間來理解 —— 我們之前沒有任何類似的行為。這是理解事物如何運作的最好方法。

可以使用CSS Grid來實現(xiàn)瀑布流布局?

很多同學(xué)有一種誤解,認(rèn)為網(wǎng)格布局與瀑布流或Pinterest布局一樣的。這通常是基于在網(wǎng)格布局中自動放置網(wǎng)格項目,這樣的效果看上去的確有點像瀑布流布局。在下一個示例中,我有一個布局,使用grid-auto-flow設(shè)置為dense,實現(xiàn)網(wǎng)格項目自動流的布局。這將導(dǎo)致網(wǎng)格項目從源程序中取出,并嘗試在網(wǎng)格填充空白區(qū)域。

然而這并不是真正的瀑布流布局,因為我們?nèi)匀挥幸粋€網(wǎng)格(具有行和列),并且潛在的網(wǎng)格項目從源代碼中移出。一個真正的瀑布流布局將使事物在源代碼中工作。項目被推上去填充部分空間。它更像是在兩個維度上做Flexbox布局。

你可以通過對所有的Grid項目進行定位處理來得到一個瀑布流外觀的網(wǎng)格布局,但是自動流的瀑布流布局,網(wǎng)格布局還無法具備這方面的能力。不過,未來的規(guī)范正在做這方面的考慮。

如何向網(wǎng)格區(qū)域添加背景和邊框?

一個網(wǎng)格尚未完成的問題,網(wǎng)格區(qū)域本身的背景和邊框的樣式。能在網(wǎng)格區(qū)域上直接添加背景和邊框的樣式嗎?到目前是不可能的,如果要實現(xiàn)這樣的一個效果需要插入一個元素或者添加一個偽元素來完成。

下面的這個示例中,我在網(wǎng)格中通過偽元素來完成,將其放置在基于行的位置,然后添加一個背景和邊框到該網(wǎng)格區(qū)域。

有時候可以繞過背景和邊框來實現(xiàn),比如通過網(wǎng)格間距(grid-gap) —— 用一個1px來模擬背景或邊框,比如下面的這個示例:

為了能夠?qū)W(wǎng)格區(qū)域進行適當(dāng)?shù)臉邮交?,我們需要引入網(wǎng)格區(qū)域偽元素的概念,這是一種特殊的生成內(nèi)容。在 CSS WG上有一個關(guān)于這方面的問題,所以你可以在這里參加討論,把你的想法與大家一起參與討論。

跨越到網(wǎng)格的末端

網(wǎng)格布局具有隱式和顯式網(wǎng)格的概念。顯式網(wǎng)格是我們使用grid-template-rows和grid-template-columns定義的網(wǎng)格。這個網(wǎng)格軌道定義了顯式網(wǎng)格的范圍。當(dāng)我們在顯式網(wǎng)格之外放置一個網(wǎng)格項目,或者我們通過自動旋轉(zhuǎn)更多的網(wǎng)格項目時,隱式網(wǎng)格就將被創(chuàng)建。

除非你使用grid-auto-rows或grid-auto-columns創(chuàng)建的網(wǎng)格軌道,否則在隱式網(wǎng)格中創(chuàng)建的網(wǎng)格軌道的大小將是自動的。

在很多情況下,隱式和顯式網(wǎng)格的渲染行為是相同的,對于很多的布局,你會發(fā)現(xiàn)你定義了列,然后允許將行創(chuàng)建為隱式網(wǎng)格。不同的是,當(dāng)你開始使用負的行號來引用網(wǎng)格的最后一行時,你會發(fā)現(xiàn)還是有一定區(qū)別的。

對于網(wǎng)格布局中的寫作模式。在從左到右的語言(ltr)中,列第一行是在左邊,而你可以用-1來指向右邊的列。在從右到左的語言(rtl)中,列的第一行在右側(cè),而-1則指向左邊的列。

或許你已經(jīng)發(fā)現(xiàn)了,只有顯式的網(wǎng)格才可以向后計數(shù)。如果你在隱式網(wǎng)格中添加了行,然后嘗試以-1來指定目標(biāo),你將會發(fā)現(xiàn)你得到是顯式網(wǎng)格的最后網(wǎng)格線,而不是實際網(wǎng)格最末端的網(wǎng)格線。

百分比的問題

在文章開頭之處,我描述了網(wǎng)格布局與之前的布局方法與眾不同之處。由于浮動和基于Flexbox的網(wǎng)格的限制,我們需要變得擅長計算百分比來做布局,所以大多數(shù)人做的第一件事就是嘗試在他們的網(wǎng)格布局中使用相同的方法。然而,在這樣做之前不要忘記我們有一個新單位fr。這個單位是專門為網(wǎng)格布局設(shè)計的,因為網(wǎng)格設(shè)置父元素的大小。

fr單位允許我們分配可用網(wǎng)格布局中的可用空間。其通過查看網(wǎng)格容器中可用的空間(去掉間距所需的空間、固定寬度的網(wǎng)格項目或定義網(wǎng)格軌道),然后按照我們?yōu)榫W(wǎng)格軌道指定的比例來對剩余的網(wǎng)格空間進行分配。這意味著,我們使用浮動或Flexbox布局的場景,必須有靈活的間距。

在大多數(shù)情況下,fr單位是一個比百分比更好的選擇。你可能選擇使用百分比的原因是你需要一個網(wǎng)格布局,以便與其他元素匹配使用其他布局方法,并依賴于百分比大小。然而,如果不是這樣的話,看看fr單位是否能滿足你的需求,然后對其進行計算。

網(wǎng)格可以嵌套使用?

網(wǎng)格項目也可以成為網(wǎng)格容器,就好比Flex項目也可以成為一個Flex容器一樣。但是,這些嵌套網(wǎng)格也父網(wǎng)格沒有任何關(guān)系,因此不能使用它們與其他嵌套網(wǎng)格對齊內(nèi)部元素。

在將來的網(wǎng)格布局中,很可能會有一種創(chuàng)建嵌套網(wǎng)格的方法,它可以維護與父網(wǎng)格的關(guān)系。這意味著,除了網(wǎng)格的直接子節(jié)點,其他網(wǎng)格項目可能參與整個網(wǎng)格布局。

網(wǎng)格布局有對應(yīng)的Polyfill嗎?

我經(jīng)常會被問到是否有網(wǎng)格布局的Polyfill,大家都想知道是否有一種方法可以支持舊的瀏覽器。

我的建議是,這并不是你需要做的事情。這可能會為那些已經(jīng)在努力渲染現(xiàn)代網(wǎng)站的瀏覽器造成一定的性能影響,帶來不好的用戶體驗。如果你南非要較舊的瀏覽器與現(xiàn)代瀏覽器相同,那么你可能要考慮在這個項目中是否使用網(wǎng)格布局。不過,在大多數(shù)情況下,可以使用較老的方法來為不支持的設(shè)備創(chuàng)建一個簡單的降級處理,而不需要創(chuàng)建兩個完全不同的CSS代碼。這方面真的需要用一篇文章來詳細闡述,所以我將盡快在Smashing Magazine發(fā)布這方面的教程。

調(diào)試網(wǎng)格布局

當(dāng)你開始使用網(wǎng)格布局時,你肯定希望能看到你的網(wǎng)格和其網(wǎng)格項目是如何布局的。我建議你使用Firefox Nightly,并在Firefox 瀏覽器開發(fā)者工具中使用網(wǎng)格檢查器。如果你選擇一個網(wǎng)格,可以點擊這個小網(wǎng)格圖標(biāo) —— 我喜歡把它想像成一個華夫餅(Waffle) —— 來顯示網(wǎng)格。

如對本文有疑問,請?zhí)峤坏浇涣髡搲瑥V大熱心網(wǎng)友會為你解答??! 點擊進入論壇

發(fā)表評論 (463人查看,0條評論)
請自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號