<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          收藏!40 個(gè) CSS 布局技巧

          共 17012字,需瀏覽 35分鐘

           ·

          2020-09-21 16:12


          CSS是Web開發(fā)中不可或缺的一部分,隨著Web技術(shù)的不斷革新,CSS也變得更加強(qiáng)大。CSS的眾多屬性你知道了多少?具體開發(fā)中該使用什么屬性才最適合恰當(dāng)?如今的一些CSS屬性可以讓我們節(jié)約更多的時(shí)間。比如在Web布局中,現(xiàn)代CSS特性就可以更好的幫助我們快速實(shí)現(xiàn)如等高布局,水平垂直居中,經(jīng)典的圣杯布局、寬高比例、頁腳保持在底部等效果。淘系前端技術(shù)專家大漠將詳細(xì)介紹一些不同的CSS屬性來實(shí)現(xiàn)這些效果,希望對同學(xué)們有所幫助。

          來源公眾號(hào):阿里技術(shù)

          https://mp.weixin.qq.com/s/9f4UaZWzYSJB_ZdwhS3A3A


          一? 水平垂直居中

          如何實(shí)現(xiàn)水平垂直居中可以說是CSS面試題中的經(jīng)典面試題,在多年前這個(gè)面試題給很多同學(xué)都帶來了困惑,但Flexbxo布局模塊和CSS Grid布局模塊的到來,可以說實(shí)現(xiàn)水平垂直居中已是非常的容易。

          Flexbox中實(shí)現(xiàn)水平垂直居中

          在Flexbox布局模塊中,不管是單行還是多行,要讓它們在容器中水平垂直居中都是件易事,而且方法也有多種。最常見的是在Flex容器上設(shè)置對齊方式,在Flex項(xiàng)目上設(shè)置 margin:auto

          先來看在Flex容器上設(shè)置對齊方式。

          Flex容器和Flex項(xiàng)目上設(shè)置對齊方式

          你可能已經(jīng)知道在Flex容器上設(shè)置 justify-contentalign-items 的值為 center 時(shí),可以讓元素在Flex容器中達(dá)到水平垂直居中的效果。來看一個(gè)示例:

          <div class="flex__container">    <div class="flex__item">div>div>
          /* CSS */.flex__container { display: flex; justify-content: center; align-items: center;}

          效果如下:


          這種方式特別適應(yīng)于讓Icon圖標(biāo)在容器中水平垂直居中,不同的是在Icon圖標(biāo)容器上顯示設(shè)置 display: inline-flex。比如下面這個(gè)示例:

          <div class="flex__container">    <svg> svg>div>
          /* CSS */.flex__container { display: inline-flex; align-items: center; justify-content: center;}

          效果如下:


          在這種模式之下,如果要讓多個(gè)元素實(shí)現(xiàn)水平垂直居中的效果,那還需要加上 flex-direction: column,比如:

          <div class="flex__container">    <div class="avatar">:)div>    <div class="media__heading">div>    <div class="media__content">div>    <div class="action">div>div>
          /* CSS */.flex__container { display: flex; flex-direction: column; justify-content: center; align-items: center;}

          效果如下:


          在Flexbox布局中,還可以像下面這樣讓Flex項(xiàng)目在Flex容器中達(dá)到水平垂直居中的效果:

          <div class="flex__container">    <div class="flex__item">div>div>
          /* CSS */.flex__container { display: flex; // 或inline-flex justify-content: center;}
          .flex__item { align-self: center;}

          效果如下:


          如果在Flex容器中有多個(gè)Flex項(xiàng)目時(shí),該方法同樣有效:

          .flex__container {    display: flex; // 或inline-flex    justify-content: center;}
          .flex__container > * { align-self: center;}

          比如下面這個(gè)效果:


          除此之外,還可以使用 place-content: center 讓Flex項(xiàng)目實(shí)現(xiàn)水平垂直居中:

          .flex__container {    display: flex;    place-content: center;}
          .flex__item { align-self: center;}

          效果如下:


          或者換:

          .flex__container {    display: flex;    place-content: center;    place-items: center;}

          效果如下:


          這兩種方式同樣適用于Flex容器中有多個(gè)Flex項(xiàng)目的情景:

          .flex__container {    display: flex;    flex-direction: column;    place-content: center;}
          .flex__container > * { align-self: center;}
          // 或
          .flex__container { display: flex; flex-direction: column; place-content: center; place-items: center;}

          效果如下:


          可能很多同學(xué)對于 place-contentplace-items 會(huì)感到陌生。其實(shí) place-content align-contentjustify-content 的簡寫屬性;而 place-itemsalign-itemsjustify-items 的簡寫屬性。即:

          .flex__container {    place-content: center;    place-items: center;}

          等效于:

          .flex__container {    align-content: center;    justify-content: center;
          align-items: center; justify-items: center;}

          雖然擴(kuò)展出來有四個(gè)屬性,但最終等效于:

          .flex__container {    display: flex;    align-items: center;    justify-content: center;}
          // 多行.flex__container { display: flex; flex-direction: column; align-items: center; justify-content: center;}

          在Flex項(xiàng)目上設(shè)置margin: auto

          如果在Flex容器中只有一個(gè)Flex項(xiàng)目,還可以顯式在Flex項(xiàng)目中顯式設(shè)置 margin 的值為auto,這樣也可以讓Flex項(xiàng)目在Flex容器中水平垂直居中。例如:

          .flex__container {    display: flex; // 或 inline-flex}
          .flex__item { margin: auto;}

          效果如下:


          整個(gè)過程,你可以通過下面這個(gè)示例來體驗(yàn)。嘗試著選中不同方向的 margin 值:


          Grid中實(shí)現(xiàn)水平垂直居中

          CSS Grid布局可以說是現(xiàn)代Web布局中的銀彈。它也是到目前為止布局系統(tǒng)中唯一一個(gè)二維布局系統(tǒng)。

          在CSS Grid布局中,只需要僅僅的幾行代碼也可以快速的幫助我們實(shí)現(xiàn)水平垂直居中的效果。比如下面這個(gè)示例:

          <div class="grid__container">    <div class="grid__item">div>div>
          /* CSS */.grid { display: grid; // 或 inline-grid place-items: center}

          效果如下:


          在CSS Grid布局模塊中,只要顯式設(shè)置了 display: grid(或 inline-grid)就會(huì)創(chuàng)建Grid容器和Grid項(xiàng)目,也會(huì)自動(dòng)生成網(wǎng)格線,即行和列(默認(rèn)為一行一列)。



          在沒有顯式地在Grid容器上設(shè)置 grid-template-columnsgrid-template-rows,瀏覽器會(huì)將Grid容器默認(rèn)設(shè)置為Grid內(nèi)容大小:


          這種方法也適用于CSS Grid容器中有多個(gè)子元素(Grid項(xiàng)目),比如:

          <div class="grid__container">    <div class="avatar">:)div>    <div class="media__heading">div>    <div class="media__content">div>    <div class="action">div>div>

          這個(gè)時(shí)候你看到的效果如下:


          而且 palce-items 適用于每個(gè)單元格。這意味著它將居中單元格的內(nèi)容。比如下面這個(gè)示例:

          <div class="grid__container">    <div class="grid__item">        <h3>Special title treatmenth3>        <p>With supporting text below as a natural lead-in to additional content.p>        <div class="action">Go somewherediv>    div>div>
          /* CSS */.grid__container { display: grid; place-items: center; grid-template-columns: repeat(2, 1fr); gap: 2vh;}

          .grid__item { display: grid; place-items: center;}

          效果如下:


          二? 等高布局

          等高布局也是Web中非常常見的一種布局方式,而且實(shí)現(xiàn)等高布局的方案也有很多種。這里我們主要來看Flexbox布局模塊和Grid布局模塊給我們帶來了什么樣的變化。

          在Flexbox和Grid布局模塊中,讓我們實(shí)現(xiàn)等高布局已經(jīng)是非常的簡單了,比如:

          <flex__container>    <flex__item>flex__item>    <flex__item>flex__item>    <flex__item>flex__item>flex__container>
          /* CSS */.flex__container { display: flex; // 或 inline-flex}

          簡單地說,在容器上顯式設(shè)置了 display 的值為 flexinline-flex,該容器的所有子元素的高度都相等,因?yàn)槿萜鞯?align-items 的默認(rèn)值為 stretch

          這個(gè)時(shí)候你看到的效果如下:


          這種方式特別適用于卡片組件中:


          在Grid布局模塊中類似:

          <grid__container>    <grid__item>grid__item>    <grid__item>grid__item>    <grid__item>grid__item>grid__container>
          /* CSS */.grid__container { display: grid; grid-template-columns: 20vw 1fr 20vw; /* 根據(jù)需求調(diào)整值*/}

          效果如下:


          同樣在一些卡片類布局中運(yùn)用:


          如果需求有所調(diào)整,比如在Flex項(xiàng)目 或 Grid項(xiàng)目的子元素高度和容器高度相同。

          <flex__container>    <flex__item>        <content>content>    flex__item>flex__container>
          /* CSS */.flex__container { display: flex;}
          .content { height: 100%}
          // 或.grid__container { display: grid; grid-auto-flow: column;}
          .content { height: 100%;}

          效果如下:


          三? Sticky Footer

          首先用下圖來描述什么是Sticky Footer布局效果:



          Sticky Footer實(shí)現(xiàn)方案和等高、垂直居中一樣,同樣有很多種方案可以實(shí)現(xiàn)。

          比如像下面這樣的結(jié)構(gòu):

          <header>header><main>main><footer>footer>

          先來看Flexbox布局模塊中的實(shí)現(xiàn)方案:

          body {    display: flex;    flex-direction: column;}
          footer { margin-top: auto;}


          可以嘗試著在 main 區(qū)域右下角向下拖動(dòng),改變主內(nèi)容區(qū)域的高度,你會(huì)發(fā)現(xiàn)“當(dāng)內(nèi)容不足一屏?xí)r,
          會(huì)在頁面的最底部,當(dāng)內(nèi)容超出一屏?xí)r,
          會(huì)自動(dòng)往后延后”。

          在Flexbox布局中,還可以在
          區(qū)域上設(shè)置下面的樣式,達(dá)到相等的效果:

          body {    display: flex;    flex-direction: column;}
          main { flex: 1 0 auto;}

          效果如下:


          中的 flex: 1 0 auto 相當(dāng)于是:

          main {    flex-grow: 1; /*容器有剩余空間時(shí),main區(qū)域會(huì)擴(kuò)展*/    flex-shrink: 0; /*容器有不足空間時(shí),main區(qū)域不會(huì)收縮*/    flex-basis: auto; /*main區(qū)域高度的基準(zhǔn)值為main內(nèi)容自動(dòng)高度*/}

          如果你想省事的話,可以在 main 上顯式設(shè)置 flex-grow:1,因?yàn)?flex-shrinkflex-basis 的默認(rèn)值為 1auto

          在CSS Grid布局中我們可以借助 1fr
          區(qū)域根據(jù)Grid容器剩余空間來做計(jì)算。

          .grid__container {    display: grid;    grid-template-rows: auto 1fr auto;}

          效果如下:


          四? 均分列

          在Web布局中,很多時(shí)候會(huì)對列做均分布局,最為常見的就是在移動(dòng)端的底部Bar,比如下圖這樣的一個(gè)效果:


          在Flexbox和Grid還沒出現(xiàn)之前,如果希望真正的做到均分效果,可以用 100%(或 100vw)除以具體的列數(shù)。比如:

          <container>    <column>column>    <column>column>    <column>column>container>
          /* CCSS */.container { inline-size: 50vw; min-inline-size: 320px; display: flex-row;}
          .column { float: left; width: calc(100% / 3);}

          效果如下:


          通過瀏覽器調(diào)試器中可以發(fā)現(xiàn),現(xiàn)個(gè)列的寬度都是相等的:


          在Flexbox和Grid布局中,實(shí)現(xiàn)上面的效果會(huì)變得更容易地多。先來看Flexbox中的布局:

          <flex__container>    <flex__item>flex__item>    <flex__item>flex__item>    <flex__item>flex__item>flex__container>
          /* CSS */.flex__container { inline-size: 50vw; display: flex;}
          .flex__item { flex: 1;}

          效果如下:


          在Flexbox布局模塊中,當(dāng)flex取的值是一個(gè)單值(無單位的數(shù)),比如示例中的 flex:1,它會(huì)當(dāng)作顯式的設(shè)置了 flex-grow: 1。瀏覽器計(jì)算出來的 flex


          接下來看Grid中如何實(shí)現(xiàn)上例的效果:

          <grid__container>    <grid__item>grid__item>    <grid__item>grid__item>    <grid__item>grid__item>grid__container>
          /* CSS */.grid__container { display: grid; grid-template-columns: repeat(3, 1fr); /*這里的3表示具體的列數(shù)*/}

          最終的效果是相同的:


          這樣的布局方式也適用于其他的布局中。但不管是Flexbox還是Grid布局中,都存在一定的缺陷,當(dāng)容器沒有足夠的空間容納Flex項(xiàng)目(或Grid項(xiàng)目)時(shí),F(xiàn)lex項(xiàng)目或Grid項(xiàng)目會(huì)溢出(或隱藏,如果Flex容器或Grid容器顯式設(shè)置了 overflow:hidden):


          修復(fù)這種現(xiàn)象最簡單的方式是在Flex容器或Grid容器顯式設(shè)置一個(gè) min-width(或 min-inline-size):

          .flex__container {    min-inline-size: 300px;}

          不過話又說回來,比如我們的Flex項(xiàng)目(或Grid項(xiàng)目)是一個(gè)卡片,每張卡片寬度是相等之外,更希望容器沒有足夠空間時(shí),F(xiàn)lex項(xiàng)目(或Grid項(xiàng)目)會(huì)自動(dòng)斷行排列。

          我們繼續(xù)通過示例向大家展示。先來看Flexbox實(shí)現(xiàn)方案:

          .flex__container {    display: flex;    flex-wrap: wrap;}
          .flex__item { flex: 0 1 calc((100vw - 18vh) / 4); /* calc(100vw -18vh) / 4 是flex-basis的基準(zhǔn)值 */}


          你可以嘗試著調(diào)整瀏覽器的視窗寬度,當(dāng)瀏覽器的視窗越來越小時(shí),F(xiàn)lex容器寬度也就會(huì)越來越小,當(dāng)Flex容器小到?jīng)]有足夠的空間容納四個(gè)Flex項(xiàng)目(就此例而言),那么Flex項(xiàng)目就會(huì)斷行排列:


          基于該例,如果把Flex項(xiàng)目的 flex 值改成:

          .flex__item {    flex: 0 0 400px;}

          這個(gè)時(shí)候,當(dāng)Flex容器沒有足夠空間時(shí),F(xiàn)lex項(xiàng)目會(huì)按 flex-basis: 400px 計(jì)算其寬度,F(xiàn)lex容器沒有足夠空間時(shí),F(xiàn)lex就會(huì)斷行:


          反過來,如果Flex項(xiàng)目的值 flex 改成:

          .flex__item {    flex: 1 0 400px;}

          當(dāng)Flex容器沒有足夠空間排列Flex項(xiàng)目時(shí),F(xiàn)lex項(xiàng)目會(huì)按 flex-basis: 400px 計(jì)算其寬度,F(xiàn)lex會(huì)斷行,并且同一行出現(xiàn)剩余空間時(shí),F(xiàn)lex項(xiàng)目會(huì)擴(kuò)展,占滿整個(gè)Flex容器:


          在Grid中實(shí)現(xiàn)類似的效果要更復(fù)雜一點(diǎn)。可以使用 repeat() 函數(shù),1fr 以及 auto-fit 等特性:

          .grid__container {    display: grid;    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));    gap: 2vh;}

          效果如下:


          如果你對這方面知識(shí)感興趣的話,還可以移步閱讀《Container Query Solutions with CSS Grid and Flexbox》一文。

          其實(shí)在Grid中與 auto-fit 對比的值還有一個(gè)叫 auto-fill。但兩者的差異是非常地大,用下圖來描述 auto-fitauto-fill 的差異:


          另外這種方式也是到目前為止一種不需要借助CSS媒體查詢就可以實(shí)現(xiàn)響應(yīng)式布局效果。

          五? 圣杯布局

          圣杯布局(Holy Grail Layout))是Web中典型的布局模式。看上去像下圖這樣:


          對于圣杯布局而言,HTML結(jié)構(gòu)是有一定的要求,那就是內(nèi)容為先:

          <header>header><main>    <article>article>     <nav>nav>    <aside>aside>main><footer>footer>

          在這里主要還是和大家一起探討,如何使用Flexbox和Grid布局模塊來實(shí)現(xiàn)圣杯布局。先來看Flexbox實(shí)現(xiàn)方案:

          body {    width: 100vw;    display: flex;    flex-direction: column;}
          main { flex: 1; min-height: 0;
          display: flex; align-items: stretch; width: 100%;}
          footer { margin-top: auto;}
          nav { width: 220px; order: -1;}
          article { flex: 1;}
          aside { width: 220px;}

          效果如下:


          通過在 navasidearticle 上顯式設(shè)置 order 的值,可以很好的控制這三個(gè)區(qū)域的布局順序。比如說,希望

          nav {    order: 0;}
          aside { order: -1;}

          效果如下:


          注意,order的默認(rèn)值為0,值越大越排在后面!


          在上例的基礎(chǔ)上,借助CSS媒體對象的特性,可以很容易實(shí)現(xiàn)響應(yīng)式的圣杯布局效果:

          @media screen and (max-width: 800px) {    main {        flex-direction: column;    }
          nav, aside { width: 100%; }}

          效果如下:


          嘗試著拖動(dòng)瀏覽器來改變視窗大小,你可以看到如下圖的效果:


          在Grid布局模塊中,實(shí)現(xiàn)圣杯布局要比Flexbox布局模塊中更容易,而且更靈活。在CSS Grid布局模塊中,HTML結(jié)構(gòu)可以更簡潔:

          <body>    <header>header>    <main>main>    <nav>nav>    <aside>aside>    <footer>footer>body>

          在CSS方面有很多種方案可以實(shí)現(xiàn)圣杯布局效果。我們先來看第一種:

          body {    display: grid;    grid-template: auto 1fr auto / 220px 1fr 220px;}
          header { grid-column: 1 / 4;}
          main { grid-column: 2 / 3; grid-row: 2 / 3;}
          nav { grid-column: 1 / 2; grid-row: 2 / 3;}
          aside { grid-column: 3 / 4; grid-row: 2 / 3;}footer { grid-column: 1 / 4;}

          效果如下:


          上面示例采用的是網(wǎng)格線來給每個(gè)區(qū)域進(jìn)行定位的:


          和Flexbox布局類似,在媒體查詢中可以改變每個(gè)網(wǎng)格區(qū)域的位置:

          @media screen and (max-width: 800px) {    body {        grid-template-rows: auto;        grid-template-columns: auto;    }
          header, main, nav, aside, footer { grid-column: 1 / 2; min-height: auto; }
          main { grid-row: 3 / 4; margin: 0; }
          nav { grid-row: 2 / 3; }
          aside { grid-row: 4 / 5; }
          footer { grid-row: 5 / 6; }}


          除了 grid-template(即 grid-template-columnsgrid-template-rows)之外,在Grid布局中還可以使用 grid-areagrid-template-areas 屬性的結(jié)合,也能很方便的實(shí)現(xiàn)CSS圣杯布局。基于上面的示例上,只需要把你的CSS調(diào)整為:

          body {    display: grid;    grid-template-areas:        "header header header"        "nav main aside"        "footer footer footer";}
          header { grid-area: header;}
          main { grid-area: main;}
          nav { grid-area: nav;}
          aside { grid-area: aside;}
          footer { grid-area: footer;}
          @media screen and (max-width: 800px) { body { grid-template-areas: "header" "nav" "main" "aside" "footer"; }}

          效果如下:


          你可能發(fā)現(xiàn)了它們之間的差異性:


          后面這個(gè)示例中,


          如果我們希望
          的區(qū)域變得更大,那么可以在 grid-template-areas 上做個(gè)調(diào)整:

          body {    display: grid;    grid-template-areas:        "header header header header header"        "nav main main main aside"        "footer footer footer footer footer";}

          效果如下:


          這個(gè)時(shí)候網(wǎng)格區(qū)域的劃分像下圖這樣:


          雖然在效果有所調(diào)整了,但還是均分狀態(tài)。更好的解決方案是,將 grid-template-areasgrid-template 結(jié)合起來使用:

          body {    display: grid;    grid-template-areas:        "header header header"        "nav main aside"        "footer footer footer";    grid-template-columns: 220px 1fr 220px;    grid-template-rows: auto 1fr auto;}
          header { grid-area: header;}
          main { grid-area: main;}
          nav { grid-area: nav;}
          aside { grid-area: aside;}
          footer { grid-area: footer;}
          @media screen and (max-width: 800px) { body { grid-template-areas: "header" "nav" "main" "aside" "footer"; grid-template-columns: 1fr; grid-template-rows: auto auto 1fr auto auto; }
          main { margin-left: 0; margin-right: 0; }}

          效果如下:


          你可以發(fā)現(xiàn),這個(gè)時(shí)候,網(wǎng)格線的區(qū)域的命名像下圖這樣:


          六? 12列網(wǎng)格布局

          12列網(wǎng)格布局最早是由960.gs提出的網(wǎng)格布局系統(tǒng):


          12列網(wǎng)格布局在設(shè)計(jì)系統(tǒng)和CSS Framework中經(jīng)常使用,比如業(yè)內(nèi)經(jīng)典的Bootstrap就采用了12列網(wǎng)格布局系統(tǒng):


          在社區(qū)中也有很多在線工具,幫助我們快速構(gòu)建12列網(wǎng)格系統(tǒng),比如 Free CSS Grid Tools & Resources For Developers 一文中羅列的工具。


          不過這里主要是想和大家一起看看在Flexbox和Grid布局模塊中是如何實(shí)現(xiàn)12列的網(wǎng)格布局系統(tǒng)。

          先來看Flexbox布局模塊。12列網(wǎng)格布局的HTMl結(jié)構(gòu)一般類似于下面這樣:

          <flex__grid>    <flex__row>        <flex__item col4>flex__item col4>        <flex__item col4>flex__item col4>        <flex__item col4>flex__item col4>    flex__row>flex__grid>

          注意,12列網(wǎng)格中,一般同一行的列數(shù)值和剛好等于12。比如上面的HTML結(jié)構(gòu),行中有三列,每列的寬度剛好四個(gè)網(wǎng)格寬度加兩個(gè)列間距。并且在計(jì)算的時(shí)候有一套成熟的計(jì)算公式:


          而且還設(shè)計(jì)上也會(huì)有所差異,比如說距離容器兩側(cè)有沒有間距等:


          這些的差異對于計(jì)算公式和樣式代碼的設(shè)計(jì)都略有差異。我們用其中一個(gè)為例:

          :root {    --gutter: 10px;    --columns: 12;    --span: 1;}
          .flex__container { display: flex; flex-direction: column; padding-left: var(--gutter); padding-right: var(--gutter);}
          .flex__row { display: flex; margin-left: calc(var(--gutter) * -1); margin-right: calc(var(--gutter) * -1);}
          .flex__row + .flex__row { margin-top: 2vh;}
          .flex__item { flex: 1 1 calc((100% / var(--columns) - var(--gutter)) * var(--span)); margin: 0 var(--gutter);}
          .flex__item1 { --span: 1;}
          .flex__item2 { --span: 2;}
          .flex__item3 { --span: 3;}
          .flex__item4 { --span: 4;}
          .flex__item5 { --span: 5;}
          .flex__item6 { --span: 6;}
          .flex__item7 { --span: 7;}
          .flex__item8 { --span: 8;}
          .flex__item9 { --span: 9;}
          .flex__item10 { --span: 10;}
          .flex__item11 { --span: 11;}
          .flex__item12 { --span: 12;}

          你會(huì)看到的效果如下:


          在該示例中采用了CSS自定義屬性相關(guān)的特性,讓整個(gè)計(jì)算變得更容易一些。

          對于使用CSS Grid布局模塊來實(shí)現(xiàn)12列網(wǎng)格布局,相對而言,不管是HTML結(jié)構(gòu)還是CSS代碼都會(huì)更簡易一些。在使用CSS Grid布局模塊實(shí)現(xiàn)12列網(wǎng)格布局,將會(huì)運(yùn)用到 repeat()minmax()gapfr 等特性。具體的來看一個(gè)示例吧。

          <grid__container>    <grid__item>grid__item>grid__container>

          我們來看CSS代碼:

          • 使用 fr 將網(wǎng)格均分為相等的值,即每列寬度都是 1 個(gè) fr;配合 repeat() 函數(shù),即 repeat(12, 1fr) 創(chuàng)建了12列網(wǎng)格。


          • 使用?gap 可以用來控制網(wǎng)格之間的間距。


          • 配合 minmax() 還可以設(shè)置網(wǎng)格最小值。


          具體的代碼如下:

          :root {    --columns: 12;    --gap: 10px;    --span: 1;}
          .grid__container { display: grid; grid-template-columns: repeat(var(--columns), 1fr); grid-template-rows: 1fr; gap: var(--gap); padding-left: calc(var(--gap) / 2); padding-right: calc(var(--gap) / 2);}
          .grid__item { min-block-size: 10vh; grid-column: span var(--span);}
          .col1 { --span: 1;}
          .col2 { --span: 2;}
          .col3 { --span: 3;}
          .col4 { --span: 4;}
          .col5 { --span: 5;}
          .col6 { --span: 6;}
          .col7 { --span: 7;}
          .col8 { --span: 8;}
          .col9 { --span: 9;}
          .col10 { --span: 10;}
          .col11 { --span: 11;}
          .col12 { --span: 12;}

          你將看到的效果如下:



          就該示例而言,grid-template-columns: repeat(12, 1fr) 創(chuàng)建網(wǎng)格如下圖所示:


          除了上述這種粗暴的方式,還可以更靈活一些,將 auto-fitminmax() 以及 grid-auto-flow: dense 等來創(chuàng)建:

          .grid__container {    padding: 1em;    display: grid;    grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));    gap: 1em;    grid-auto-flow: dense;}

          對于 .grid__item 可以通過 grid-columngrid-row 來控制網(wǎng)格項(xiàng)目的位置:


          加上 grid-auto-flow: dense 會(huì)根據(jù)Grid容器空間,Grid項(xiàng)目會(huì)自動(dòng)流到合適的位置:


          這種布局對于雜志類的布局非常的適用。有關(guān)于這方面更詳細(xì)的介紹可以閱讀@Keir Watson的《Responsive Grid Magazine Layout in Just 20 Lines of CSS》一文。

          七? 兩端對齊

          在Web布局中時(shí)常碰到兩端對齊的需求。在Flexbox布局中,時(shí)常在Flex容器中顯式設(shè)置?justify-content 的值:

          .flex__container {    display: flex;    flex-wrap: wrap;    justify-content: space-between;
          width: 100%;}

          但在末尾行,如果和前面行的個(gè)數(shù)不相同(Flex項(xiàng)目)就會(huì)出現(xiàn)下圖這樣的效果:


          像上圖這樣的效果,并不是我們所需要的,因?yàn)槲覀兿M谧詈笠恍械腇lex項(xiàng)目不足夠排列滿一行時(shí),希望Flex項(xiàng)目一個(gè)緊挨一個(gè)的排列:


          在Flexbox要實(shí)現(xiàn)上圖這樣的效果,只需要在Flex容器中添加一個(gè)偽元素:

          .flex__container::after {    content: "";    display: flex;    flex: 0 1 32vw;}

          注意,偽元素的 flex-basis 建議設(shè)置的和卡片的 flex-basis(或?qū)挾龋┑韧_@個(gè)時(shí)候你將看到像下面這樣的示例:


          不過這種方式也不是最佳的方式,當(dāng)末尾行的個(gè)數(shù)不只少一個(gè)時(shí),就會(huì)出現(xiàn)下圖這樣的效果:


          面對這樣的場景,我們需要給Flex容器添加額外的空標(biāo)簽元素:

          占位符元素?cái)?shù)量 = 每行最大的列數(shù) - 2


          但是 gap屬性出現(xiàn)之后,要實(shí)現(xiàn)這樣的效果就不難了:

          body {    padding: 1vh;}
          .flex__container { display: flex; flex-wrap: wrap; gap: 2vh;
          width: 100%;}
          .flex__item { flex: 0 1 calc((100vw - 8vh) / 4);}

          效果如下:


          注意,gap 運(yùn)用在Flexbox中到目前為止,僅得到了Firefox瀏覽器的支持。上面的示例,使用Firefox瀏覽器,你看到的效果如下:


          在CSS Grid布局中,就可以直接使用 gap

          body {    padding: 1vh;}
          .grid__container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1vh;}

          效果如下:



          八? 選擇最佳的值

          很多時(shí)候,針對不同的場景,設(shè)計(jì)師會(huì)為我們提供不同的設(shè)計(jì)風(fēng)格,比如元素大小:


          隨著 clam() 函數(shù)的到來,這一切都變得容易地多。

          clam() 函數(shù)接受三個(gè)參數(shù),即 clam(MIN, VAL, MAX),其中 MIN 表示最小值,VAL 表示首選值,MAX 表示最大值。它們之間:

          • 如果 VALMINMAX 之間,則使用 VAL 作為函數(shù)的返回值。

          • 如果 VAL 大于 MAX,則使用 MAX 作為函數(shù)的返回值。

          • 如果 VAL 小于 MIN,則使用 MIN 作為函數(shù)的返回值。


          我們來看一個(gè)示例:

          .element {    /**    * MIN = 100px    * VAL = 50vw ? 根據(jù)視窗的寬度計(jì)算    * MAX = 500px    **/
          width: clamp(100px, 50vw, 500px);}

          比如瀏覽器視窗現(xiàn)在所處的位置是1200px的寬度,那么 .element 渲染的結(jié)果如下:


          這個(gè)時(shí)候 .element 元素的 width500px。此時(shí),clamp(100px, 50vw, 500px) 相當(dāng)于 clamp(100px, 600px, 500px),對應(yīng)的 VAL 值是 600px,大于 MAX 值,那么這個(gè)時(shí)候 clamp() 函數(shù)返回的值是 MAX,即 500px,這個(gè)時(shí)候 .elementwidth 值就是 500px(即 MAX 的值)。

          如果我們把瀏覽器視窗縮小至 760px


          這個(gè)時(shí)候 .element 元素的 width50vw。此時(shí),clamp(100px, 50vw, 500px) 相當(dāng)于clamp(100px, 380px, 500px),對應(yīng)的 VAL?值是 380px,該值大于 MIN 值(100px),小于 MAX 值(500px),那么這個(gè)時(shí)候 clamp() 函數(shù)返回的值是 VAL,即 50vw,這個(gè)時(shí)候 .elementwidth 值就是 50vw(即 VAL 的值)。

          如果繼續(xù)將瀏覽器的視窗縮小至 170px


          這個(gè)時(shí)候 .element 元素的 width100px。此時(shí),clamp(100px, 50vw, 500px) 相當(dāng)于 clamp(100px, 85px, 500px),對應(yīng)的 VAL 值是 85px,該值小于 MIN 值(100px),那么這個(gè)時(shí)候 clamp() 函數(shù)返回的值是 MIN,即 100px,這個(gè)時(shí)候 .elementwidth 值就是 100px(即 MIN 的值)。

          就該示例而言,clamp(100px, 50vw, 500px) 還可以這樣來理解:

          • 元素 .element 的寬度不會(huì)小于 100px(有點(diǎn)類似于元素設(shè)置了 min-width: 100px)。


          • 元素 .element 的寬度不會(huì)大于 500px(有點(diǎn)類似于元素設(shè)置了 max-width: 500px)。


          • 首選值 VAL50vw,只有當(dāng)視窗的寬度大于 200px 且小于 1000px 時(shí)才會(huì)有效,即元素 .element 的寬度為 50vw(有點(diǎn)類似于元素設(shè)置了 width:50vw)。


          九? Logo圖標(biāo)的對齊

          我想你在Web開發(fā)中可能碰到過類似下圖的這樣的場景:


          正像上圖所示,Logo圖像的有大有小(寬度和高度都不一樣)。面對這樣的業(yè)務(wù)場景,很多時(shí)候都希望設(shè)計(jì)師能提供相同尺寸的圖像。但這樣勢必會(huì)影響Logo圖像的外觀。

          前段時(shí)間看到@Ahmad Shadeed專門寫了一篇博文《Aligning Logo Images in CSS》,就是介紹如何實(shí)現(xiàn)上圖這樣的布局效果。

          其實(shí)實(shí)現(xiàn)這樣的布局效果,主要運(yùn)用到的就是CSS的 object-fit 屬性,而這個(gè)屬性早在多年前就得到了各大主流瀏覽器的支持。

          這里我們用一個(gè)簡單的示例,來看看具體實(shí)現(xiàn)過程。先來看HTML結(jié)構(gòu):

          <ul class="brands">    <li class="brands__item">        <a href="#">            <img src="img/logo.png" alt="">        a>    li>    <li>  li>ul>

          居中對齊前面已經(jīng)介紹過了,這里主要是看圖像大小方面的處理:

          .brands {    display: grid;    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));    grid-gap: 1rem;}
          .brands__item { background: #eee;}
          .brands__item a { display: flex; justify-content: center; align-items: center; height: 100%;}
          .brands__item img { width: 130px; height: 75px; object-fit: contain;}

          這樣就能實(shí)現(xiàn)上圖的效果。你可能發(fā)現(xiàn)了,有些Logo圖像帶有背景顏色,如果讓效果更好一些,可以把CSS混合模式相關(guān)的特性運(yùn)用進(jìn)來:

          .brands__item img {    width: 130px;    height: 75px;    object-fit: contain;    mix-blend-mode: multiply;}

          這個(gè)時(shí)候,你看到的效果如下:


          object-fit 除了取值 contain 之外,還有其他幾個(gè)值:


          其實(shí)這個(gè)方案也適用于產(chǎn)品圖片,人物頭像等布局。

          小結(jié)

          文章中主要介紹了Web中一些布局的實(shí)現(xiàn)思路和具體方案。其實(shí)文章提到的效果,比如水平垂直居中、等高布局、平均分布列和Sticky Footer等,在CSS中一直有多種解決方案,只不過隨著CSS Flexbox布局模塊和CSS Grid布局模塊的到來,實(shí)現(xiàn)這些效果變得更為靈活和簡潔。

          當(dāng)然,文章中提到的只是一些最為常見的一些效果,其實(shí)在Web布局中,特別是Flexbox布局和Grid布局中還存在著很多有意思的東西,只不過因?yàn)槠脑驔]有一一羅列。如果你感興趣可以再挖掘一些出來,如果你在這方面有更好的經(jīng)驗(yàn)或方案,歡迎在下面的評(píng)論中分享。最后希望這篇文章對你平時(shí)的工作有所幫助

          》》面試官都在用的題庫,快來看看《

          瀏覽 46
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉在线电影网 | 99操逼| 亚洲五月天激情 | 久久免费少妇视频 | 免费一级特黄大学生毛片 |