<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 個 CSS 布局技巧

          共 17013字,需瀏覽 35分鐘

           ·

          2020-10-05 18:18


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

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

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


          一? 水平垂直居中

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

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

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

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

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

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

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

          效果如下:


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

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

          效果如下:


          在這種模式之下,如果要讓多個元素實現(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項目在Flex容器中達到水平垂直居中的效果:

          <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容器中有多個Flex項目時,該方法同樣有效:

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

          比如下面這個效果:


          除此之外,還可以使用 place-content: center 讓Flex項目實現(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容器中有多個Flex項目的情景:

          .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;}

          效果如下:


          可能很多同學對于 place-contentplace-items 會感到陌生。其實 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;}

          雖然擴展出來有四個屬性,但最終等效于:

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

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

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

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

          效果如下:


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




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

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

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

          <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)就會創(chuàng)建Grid容器和Grid項目,也會自動生成網(wǎng)格線,即行和列(默認為一行一列)。



          在沒有顯式地在Grid容器上設(shè)置 grid-template-columnsgrid-template-rows,瀏覽器會將Grid容器默認設(shè)置為Grid內(nèi)容大?。?/span>


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

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

          這個時候你看到的效果如下:


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

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

          在Flexbox和Grid布局模塊中,讓我們實現(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,該容器的所有子元素的高度都相等,因為容器的 align-items 的默認值為 stretch。

          這個時候你看到的效果如下:


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


          在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)整值*/}

          效果如下:


          同樣在一些卡片類布局中運用:


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

          <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實現(xiàn)方案和等高、垂直居中一樣,同樣有很多種方案可以實現(xiàn)。

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

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

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

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


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

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

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

          效果如下:


          中的 flex: 1 0 auto 相當于是:

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

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

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

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

          效果如下:


          四? 均分列

          在Web布局中,很多時候會對列做均分布局,最為常見的就是在移動端的底部Bar,比如下圖這樣的一個效果:


          在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)個列的寬度都是相等的:


          在Flexbox和Grid布局中,實現(xiàn)上面的效果會變得更容易地多。先來看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布局模塊中,當flex取的值是一個單值(無單位的數(shù)),比如示例中的 flex:1,它會當作顯式的設(shè)置了 flex-grow: 1。瀏覽器計算出來的 flex




          接下來看Grid中如何實現(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布局中,都存在一定的缺陷,當容器沒有足夠的空間容納Flex項目(或Grid項目)時,F(xiàn)lex項目或Grid項目會溢出(或隱藏,如果Flex容器或Grid容器顯式設(shè)置了 overflow:hidden):


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

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

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

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

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


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




          基于該例,如果把Flex項目的 flex 值改成:

          .flex__item {    flex: 0 0 400px;}

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


          反過來,如果Flex項目的值 flex 改成:

          .flex__item {    flex: 1 0 400px;}

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


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

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

          效果如下:


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

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


          另外這種方式也是到目前為止一種不需要借助CSS媒體查詢就可以實現(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布局模塊來實現(xiàn)圣杯布局。先來看Flexbox實現(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;}

          效果如下:


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

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

          效果如下:



          注意,order的默認值為0,值越大越排在后面!



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

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

          效果如下:


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




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

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

          在CSS方面有很多種方案可以實現(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)格線來給每個區(qū)域進行定位的:


          和Flexbox布局類似,在媒體查詢中可以改變每個網(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é)合,也能很方便的實現(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)了它們之間的差異性:


          后面這個示例中,


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

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

          效果如下:


          這個時候網(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),這個時候,網(wǎng)格線的區(qū)域的命名像下圖這樣:


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

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


          12列網(wǎng)格布局在設(shè)計系統(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布局模塊中是如何實現(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),行中有三列,每列的寬度剛好四個網(wǎng)格寬度加兩個列間距。并且在計算的時候有一套成熟的計算公式:


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


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

          :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;}

          你會看到的效果如下:


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

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

          <grid__container>    <grid__item>grid__item>grid__container>

          我們來看CSS代碼:


          • 使用 fr 將網(wǎng)格均分為相等的值,即每列寬度都是 1 個 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-column、grid-row 來控制網(wǎng)格項目的位置:


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




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

          七? 兩端對齊

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

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

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


          像上圖這樣的效果,并不是我們所需要的,因為我們希望在最后一行的Flex項目不足夠排列滿一行時,希望Flex項目一個緊挨一個的排列:


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

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

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


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


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


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



          但是 gap屬性出現(xiàn)之后,要實現(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 運用在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è)計風格,比如元素大?。?/span>


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

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


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

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

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



          我們來看一個示例:

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

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


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

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


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

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


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

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


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




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




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



          九? Logo圖標的對齊

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


          正像上圖所示,Logo圖像的有大有?。▽挾群透叨榷疾灰粯樱C鎸@樣的業(yè)務(wù)場景,很多時候都希望設(shè)計師能提供相同尺寸的圖像。但這樣勢必會影響Logo圖像的外觀。

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

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

          這里我們用一個簡單的示例,來看看具體實現(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;}

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

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

          這個時候,你看到的效果如下:


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


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

          小結(jié)

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

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



          分享前端好文,點亮?在看


          瀏覽 50
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  美女啪啪免费视频 | 午夜真实日逼视频 | 91探花在线 | 日屄在线免费视频 | 青青草这里有精品 |