css布局方式_网页布局都有哪种?一般都用什么布局?
如何實(shí)現(xiàn)水平垂直居中?可以說(shuō)是CSS面試題中的經(jīng)典面試題,在多年前這個(gè)面試題給很多同學(xué)都帶來(lái)了困惑,但?Flexbxo布局模塊?和?CSS Grid布局模塊?的到來(lái),可以說(shuō)實(shí)現(xiàn)水平垂直居中已是非常的容易。
? ?Flexbox中實(shí)現(xiàn)水平垂直居中
在Flexbox布局模塊中,不管是單行還是多行,要讓它們?cè)谌萜髦兴酱怪本又卸际羌资?#xff0c;而且方法也有多種。最常見(jiàn)的是在Flex容器上設(shè)置對(duì)齊方式,在Flex項(xiàng)目上設(shè)置margin:auto。
先來(lái)看在Flex容器上設(shè)置對(duì)齊方式。
Flex容器和Flex項(xiàng)目上設(shè)置對(duì)齊方式
你可能已經(jīng)知道在Flex容器上設(shè)置justify-content、align-items的值為center時(shí),可以讓元素在Flex容器中達(dá)到水平垂直居中的效果。來(lái)看一個(gè)示例:
/* CSS */.flex__container { display: flex; justify-content: center; align-items: center;}效果如下:
Demo(https://codepen.io/airen/embed/YzwYRRy)
這種方式特別適應(yīng)于讓Icon圖標(biāo)在容器中水平垂直居中,不同的是在Icon圖標(biāo)容器上顯示設(shè)置display: inline-flex。比如下面這個(gè)示例:
/* CSS */.flex__container { display: inline-flex; align-items: center; justify-content: center;}效果如下:
Demo(https://codepen.io/airen/embed/xxZpQNv)
在這種模式之下,如果要讓多個(gè)元素實(shí)現(xiàn)水平垂直居中的效果,那還需要加上flex-direction: column,比如:
:) /* CSS */.flex__container { display: flex; flex-direction: column; justify-content: center; align-items: center;}效果如下:
Demo(https://codepen.io/airen/embed/QWyazpZ)
在Flexbox布局中,還可以像下面這樣讓Flex項(xiàng)目在Flex容器中達(dá)到水平垂直居中的效果:
/* CSS */.flex__container { display: flex; // 或inline-flex justify-content: center;}.flex__item { align-self: center;}效果如下:
Demo(https://codepen.io/airen/embed/yLepGKW)
如果在Flex容器中有多個(gè)Flex項(xiàng)目時(shí),該方法同樣有效:
.flex__container { display: flex; // 或inline-flex justify-content: center;}.flex__container > * { align-self: center;}比如下面這個(gè)效果:
Demo(https://codepen.io/airen/embed/bGEaOjm)
除此之外,還可以使用place-content: center讓Flex項(xiàng)目實(shí)現(xiàn)水平垂直居中:
.flex__container { display: flex; place-content: center;}.flex__item { align-self: center;}效果如下:
Demo(https://codepen.io/airen/embed/gOPoZQz)
或者換:
.flex__container { display: flex; place-content: center; place-items: center;}效果如下:
Demo(https://codepen.io/airen/embed/JjGMwzE)
這兩種方式同樣適用于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;}效果如下:
Demo(https://codepen.io/airen/embed/XWXVoLd)
可能很多同學(xué)對(duì)于place-content和place-items會(huì)感到陌生。其實(shí)place-content是align-content和justify-content的簡(jiǎn)寫(xiě)屬性;而place-items是align-items和justify-items的簡(jiǎn)寫(xiě)屬性。即:
.flex__container { place-content: center; place-items: center;}等效于:
.flex__container { align-content: center; justify-content: center; align-items: center; justify-items: center;}雖然擴(kuò)展出來(lái)有四個(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;}效果如下:
Demo(https://codepen.io/airen/embed/KKVZJNp)
整個(gè)過(guò)程,你可以通過(guò)下面這個(gè)示例來(lái)體驗(yàn)。嘗試著選中不同方向的margin值:
Demo(https://codepen.io/airen/embed/gOPoqRq
? ?Grid中實(shí)現(xiàn)水平垂直居中
CSS Grid布局可以說(shuō)是現(xiàn)代Web布局中的銀彈。它也是到目前為止布局系統(tǒng)中唯一一個(gè)二維布局系統(tǒng)。
在CSS Grid布局中,只需要僅僅的幾行代碼也可以快速的幫助我們實(shí)現(xiàn)水平垂直居中的效果。比如下面這個(gè)示例:
/* CSS */.grid { display: grid; // 或 inline-grid place-items: center}效果如下:
Demo(https://codepen.io/airen/embed/zYrRYxW)
在CSS Grid布局模塊中,只要顯式設(shè)置了display: grid(或inline-grid)就會(huì)創(chuàng)建Grid容器和Grid項(xiàng)目,也會(huì)自動(dòng)生成網(wǎng)格線,即行和列(默認(rèn)為一行一列)。
在沒(méi)有顯式地在Grid容器上設(shè)置grid-template-columns和grid-template-rows,瀏覽器會(huì)將Grid容器默認(rèn)設(shè)置為Grid內(nèi)容大小:
這種方法也適用于CSS Grid容器中有多個(gè)子元素(Grid項(xiàng)目),比如:
:)這個(gè)時(shí)候你看到的效果如下:
Demo(https://codepen.io/airen/embed/PoZQoGP)
而且palce-items適用于每個(gè)單元格。這意味著它將居中單元格的內(nèi)容。比如下面這個(gè)示例:
Special title treatment
With supporting text below as a natural lead-in to additional content.
Go somewhere /* CSS */.grid__container { display: grid; place-items: center; grid-template-columns: repeat(2, 1fr); gap: 2vh;}.grid__item { display: grid; place-items: center;}效果如下:
Demo(https://codepen.io/airen/embed/mdVXdpe)
等高布局
等高布局也是Web中非常常見(jiàn)的一種布局方式,而且實(shí)現(xiàn)等高布局的方案也有很多種。這里我們主要來(lái)看Flexbox布局模塊和Grid布局模塊給我們帶來(lái)了什么樣的變化。
在Flexbox和Grid布局模塊中,讓我們實(shí)現(xiàn)等高布局已經(jīng)是非常的簡(jiǎn)單了,比如:
/* CSS */.flex__container { display: flex; // 或 inline-flex}簡(jiǎn)單地說(shuō),在容器上顯式設(shè)置了display的值為flex或inline-flex,該容器的所有子元素的高度都相等,因?yàn)槿萜鞯腶lign-items的默認(rèn)值為stretch。
這個(gè)時(shí)候你看到的效果如下:
Demo(https://codepen.io/airen/embed/NWxyOQq)
這種方式特別適用于卡片組件中:
Demo(https://codepen.io/airen/embed/OJMQoOO)
在Grid布局模塊中類似:
/* CSS */.grid__container { display: grid; grid-template-columns: 20vw 1fr 20vw; /* 根據(jù)需求調(diào)整值*/}效果如下:
Demo(https://codepen.io/airen/embed/mdVXQON)
同樣在一些卡片類布局中運(yùn)用:
Demo(https://codepen.io/airen/embed/MWKQzmE)
如果需求有所調(diào)整,比如在Flex項(xiàng)目?或?Grid項(xiàng)目的子元素高度和容器高度相同。
/* CSS */.flex__container { display: flex;}.content { height: 100%}// 或.grid__container { display: grid; grid-auto-flow: column;}.content { height: 100%;}效果如下:
Demo(https://codepen.io/airen/embed/jOWZdbo)
基于Sticky Footer
首先用下圖來(lái)描述什么是Sticky Footer布局效果:
Sticky Footer實(shí)現(xiàn)方案和等高、垂直居中一樣,同樣有很多種方案可以實(shí)現(xiàn)(//css-tricks.com/couple-takes-sticky-footer/)。
比如像下面這樣的結(jié)構(gòu):
先來(lái)看Flexbox布局模塊中的實(shí)現(xiàn)方案:
body { display: flex; flex-direction: column;}footer { margin-top: auto;}Demo(https://codepen.io/airen/embed/bGELzYy)
可以嘗試著在main區(qū)域右下角向下拖動(dòng),改變主內(nèi)容區(qū)域的高度,你會(huì)發(fā)現(xiàn)“當(dāng)內(nèi)容不足一屏?xí)r,會(huì)在頁(yè)面的最底部,當(dāng)內(nèi)容超出一屏?xí)r,會(huì)自動(dòng)往后延后”。
在Flexbox布局中,還可以在區(qū)域上設(shè)置下面的樣式,達(dá)到相等的效果:
body { display: flex; flex-direction: column;}main { flex: 1 0 auto;}效果如下:
Demo(https://codepen.io/airen/embed/zYrRXmY)
中的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)閒lex-shrink和flex-basis的默認(rèn)值為1和auto。
在CSS Grid布局中我們可以借助1fr讓區(qū)域根據(jù)Grid容器剩余空間來(lái)做計(jì)算。
.grid__container { display: grid; grid-template-rows: auto 1fr auto;}效果如下:
Demo(https://codepen.io/airen/embed/MWKQRxd)
均分列
在Web布局中,很多時(shí)候會(huì)對(duì)列做均分布局,最為常見(jiàn)的就是在移動(dòng)端的底部Bar,比如下圖這樣的一個(gè)效果:
在Flexbox和Grid還沒(méi)出現(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);}效果如下:
Demo(https://codepen.io/airen/embed/LYGQoxL)
通過(guò)瀏覽器調(diào)試器中可以發(fā)現(xiàn),現(xiàn)個(gè)列的寬度都是相等的:
在Flexbox和Grid布局中,實(shí)現(xiàn)上面的效果會(huì)變得更容易地多。先來(lái)看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;}效果如下:
Demo(https://codepen.io/airen/embed/yLevWEe)
在Flexbox布局模塊中,當(dāng)flex取的值是一個(gè)單值(無(wú)單位的數(shù)),比如示例中的flex:1,它會(huì)當(dāng)作顯式的設(shè)置了flex-grow: 1。瀏覽器計(jì)算出來(lái)的flex:
接下來(lái)看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ù)*/}最終的效果是相同的:
Demo(https://codepen.io/airen/embed/NWxyVQP)
這樣的布局方式也適用于其他的布局中。但不管是Flexbox還是Grid布局中,都存在一定的缺陷,當(dāng)容器沒(méi)有足夠的空間容納Flex項(xiàng)目(或Grid項(xiàng)目)時(shí),Flex項(xiàng)目或Grid項(xiàng)目會(huì)溢出(或隱藏,如果Flex容器或Grid容器顯式設(shè)置了overflow:hidden):
修復(fù)這種現(xiàn)象最簡(jiǎn)單的方式是在Flex容器或Grid容器顯式設(shè)置一個(gè)min-width(或min-inline-size):
.flex__container { min-inline-size: 300px;}不過(guò)話又說(shuō)回來(lái),比如我們的Flex項(xiàng)目(或Grid項(xiàng)目)是一個(gè)卡片,每張卡片寬度是相等之外,更希望容器沒(méi)有足夠空間時(shí),Flex項(xiàng)目(或Grid項(xiàng)目)會(huì)自動(dòng)斷行排列。
我們繼續(xù)通過(guò)示例向大家展示。先來(lái)看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)值 */}Demo(https://codepen.io/airen/embed/dyGdBpw)
你可以嘗試著調(diào)整瀏覽器的視窗寬度,當(dāng)瀏覽器的視窗越來(lái)越小時(shí),Flex容器寬度也就會(huì)越來(lái)越小,當(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容器沒(méi)有足夠空間時(shí),Flex項(xiàng)目會(huì)按flex-basis: 400px計(jì)算其寬度,Flex容器沒(méi)有足夠空間時(shí),Flex就會(huì)斷行:
反過(guò)來(lái),如果Flex項(xiàng)目的值flex改成:
.flex__item { flex: 1 0 400px;}當(dāng)Flex容器沒(méi)有足夠空間排列Flex項(xiàng)目時(shí),Flex項(xiàng)目會(huì)按flex-basis: 400px計(jì)算其寬度,Flex會(huì)斷行,并且同一行出現(xiàn)剩余空間時(shí),Flex項(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;}效果如下:
Demo(https://codepen.io/airen/embed/RwrQzeN)
如果你對(duì)這方面知識(shí)感興趣的話,還可以移步閱讀《Container Query Solutions with CSS Grid and Flexbox(//moderncss.dev/container-query-solutions-with-css-grid-and-flexbox/)》一文。
其實(shí)在Grid中與auto-fit對(duì)比的值還有一個(gè)叫auto-fill。但兩者的差異是非常地大,用下圖來(lái)描述auto-fit和auto-fill的差異:
另外這種方式也是到目前為止一種不需要借助CSS媒體查詢就可以實(shí)現(xiàn)響應(yīng)式布局效果。
圣杯布局
圣杯布局(Holy Grail Layout)(//en.wikipedia.org/wiki/Holygrail(web_design))是Web中典型的布局模式(//alistapart.com/article/holygrail/)。看上去像下圖這樣:
對(duì)于圣杯布局而言,HTML結(jié)構(gòu)是有一定的要求,那就是內(nèi)容為先:
<header>header><main> <article>article> <nav>nav> <aside>aside>main><footer>footer>在這里主要還是和大家一起探討,如何使用Flexbox和Grid布局模塊來(lái)實(shí)現(xiàn)圣杯布局。先來(lái)看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;}效果如下:
Demo(https://codepen.io/airen/embed/rNxJXYb)
通過(guò)在nav、aside和article上顯式設(shè)置order的值,可以很好的控制這三個(gè)區(qū)域的布局順序。比如說(shuō),希望在之前排列,只需要在上面的示例基礎(chǔ)上做一點(diǎn)點(diǎn)調(diào)整:
nav { order: 0;}aside { order: -1;}效果如下:
注意,order的默認(rèn)值為0,值越大越排在后面!
在上例的基礎(chǔ)上,借助CSS媒體對(duì)象的特性,可以很容易實(shí)現(xiàn)響應(yīng)式的圣杯布局效果:
@media screen and (max-width: 800px) { main { flex-direction: column; } nav, aside { width: 100%; }}效果如下:
Demo(https://codepen.io/airen/embed/gOPvVZX)
嘗試著拖動(dòng)瀏覽器來(lái)改變視窗大小,你可以看到如下圖的效果:
在Grid布局模塊中,實(shí)現(xiàn)圣杯布局要比Flexbox布局模塊中更容易,而且更靈活。在CSS Grid布局模塊中,HTML結(jié)構(gòu)可以更簡(jiǎn)潔:
<body> <header>header> <main>main> <nav>nav> <aside>aside> <footer>footer>body>在CSS方面有很多種方案可以實(shí)現(xiàn)圣杯布局效果。我們先來(lái)看第一種:
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;}效果如下:
Demo(https://codepen.io/airen/embed/PoZRYPa)
上面示例采用的是網(wǎng)格線來(lái)給每個(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; }}Demo(https://codepen.io/airen/embed/vYLRBaa)
除了grid-template(即grid-template-columns和grid-template-rows)之外,在Grid布局中還可以使用grid-area和grid-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"; }}效果如下:
Demo(https://codepen.io/airen/embed/LYGdRrG)
你可能發(fā)現(xiàn)了它們之間的差異性:
后面這個(gè)示例中,、和區(qū)域?qū)挾认嗟取_@是因?yàn)槲覀兪纠型ㄟ^(guò)grid-template-areas來(lái)聲明網(wǎng)格,在使用grid-template-areas創(chuàng)建網(wǎng)格時(shí),其實(shí)也隱式的創(chuàng)建了網(wǎng)格線,只不過(guò)他和grid-template不同的是grid-template可以顯式的指定網(wǎng)格軌道大小,而grid-template-areas在該示例中相當(dāng)于網(wǎng)格軌道大小都是1fr。
如果我們希望的區(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";}效果如下:
Demo(https://codepen.io/airen/embed/QWymKYZ)
這個(gè)時(shí)候網(wǎng)格區(qū)域的劃分像下圖這樣:
雖然在效果有所調(diào)整了,但還是均分狀態(tài)。更好的解決方案是,將grid-template-areas和grid-template結(jié)合起來(lái)使用:
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; }}效果如下:
Demo(https://codepen.io/airen/embed/OJMvRev)
你可以發(fā)現(xiàn),這個(gè)時(shí)候,網(wǎng)格線的區(qū)域的命名像下圖這樣:
12列網(wǎng)格布局
12列網(wǎng)格布局最早是由960.gs提出的網(wǎng)格布局系統(tǒng)(//960.gs/):
12列網(wǎng)格布局在設(shè)計(jì)系統(tǒng)和CSS Framework中經(jīng)常使用,比如業(yè)內(nèi)經(jīng)典的Bootstrap(//getbootstrap.com/)就采用了12列網(wǎng)格布局系統(tǒng):
在社區(qū)中也有很多在線工具,幫助我們快速構(gòu)建12列網(wǎng)格系統(tǒng),比如?Free CSS Grid Tools & Resources For Developers(//1stwebdesigner.com/free-css-grid-tools-resources/)?一文中羅列的工具。
Demo?(http://paulhebertdesigns.com/gridley/)
不過(guò)這里主要是想和大家一起看看在Flexbox和Grid布局模塊中是如何實(shí)現(xiàn)12列的網(wǎng)格布局系統(tǒng)。
先來(lái)看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ì)有所差異,比如說(shuō)距離容器兩側(cè)有沒(méi)有間距等:
這些的差異對(duì)于計(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ì)看到的效果如下:
Demo(https://codepen.io/airen/embed/YzwaxwX)
在該示例中采用了CSS自定義屬性相關(guān)的特性,讓整個(gè)計(jì)算變得更容易一些。
對(duì)于使用CSS Grid布局模塊來(lái)實(shí)現(xiàn)12列網(wǎng)格布局,相對(duì)而言,不管是HTML結(jié)構(gòu)還是CSS代碼都會(huì)更簡(jiǎn)易一些。在使用CSS Grid布局模塊實(shí)現(xiàn)12列網(wǎng)格布局,將會(huì)運(yùn)用到repeat()、minmax()、gap和fr等特性。具體的來(lái)看一個(gè)示例吧。
<grid__container> <grid__item>grid__item>grid__container>我們來(lái)看CSS代碼:
使用fr將網(wǎng)格均分為相等的值,即每列寬度都是1個(gè)fr;配合repeat()函數(shù),即repeat(12, 1fr)創(chuàng)建了12列網(wǎng)格
使用gap可以用來(lái)控制網(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;}你將看到的效果如下:
Demo(https://codepen.io/airen/embed/yLeKPPb)
就該示例而言,grid-template-columns: repeat(12, 1fr)創(chuàng)建網(wǎng)格如下圖所示:
除了上述這種粗暴的方式,還可以更靈活一些,將auto-fit、minmax()以及grid-auto-flow: dense等來(lái)創(chuàng)建:
.grid__container { padding: 1em; display: grid; grid-template-columns: repeat(auto-fit, minmax(60px, 1fr)); gap: 1em; grid-auto-flow: dense;}對(duì)于.grid__item可以通過(guò)grid-column、grid-row來(lái)控制網(wǎng)格項(xiàng)目的位置:
Demo(https://codepen.io/airen/embed/QWymabq)
加上grid-auto-flow: dense會(huì)根據(jù)Grid容器空間,Grid項(xiàng)目會(huì)自動(dòng)流到合適的位置:
這種布局對(duì)于雜志類的布局非常的適用。有關(guān)于這方面更詳細(xì)的介紹可以閱讀@Keir Watson的《Responsive Grid Magazine Layout in Just 20 Lines of CSS(//css-tricks.com/responsive-grid-magazine-layout-in-just-20-lines-of-css/)》一文。
兩端對(duì)齊
在Web布局中時(shí)常碰到兩端對(duì)齊的需求。在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í)候你將看到像下面這樣的示例:
Demo(https://codepen.io/airen/embed/QWymaam)
不過(guò)這種方式也不是最佳的方式,當(dāng)末尾行的個(gè)數(shù)不只少一個(gè)時(shí),就會(huì)出現(xiàn)下圖這樣的效果:
面對(duì)這樣的場(chǎng)景,我們需要給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);}效果如下:
Demo(https://codepen.io/airen/embed/YzwaYBN)
注意,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;}效果如下:
Demo(https://codepen.io/airen/embed/eYJMVbz)
選擇最佳的值
很多時(shí)候,針對(duì)不同的場(chǎng)景,設(shè)計(jì)師會(huì)為我們提供不同的設(shè)計(jì)風(fēng)格,比如元素大小:
隨著clam()函數(shù)的到來(lái),這一切都變得容易地多。
clam()函數(shù)接受三個(gè)參數(shù),即?clam(MIN, VAL, MAX),其中MIN表示最小值,VAL表示首選值,MAX表示最大值。它們之間:
如果VAL在MIN和MAX之間,則使用VAL作為函數(shù)的返回值;
如果VAL大于MAX,則使用MAX作為函數(shù)的返回值;
如果VAL小于MIN,則使用MIN作為函數(shù)的返回值
我們來(lái)看一個(gè)示例:
.element { /** * MIN = 100px * VAL = 50vw ? 根據(jù)視窗的寬度計(jì)算 * MAX = 500px **/ width: clamp(100px, 50vw, 500px);}比如瀏覽器視窗現(xiàn)在所處的位置是1200px的寬度,那么.element渲染的結(jié)果如下:
這個(gè)時(shí)候.element元素的width是500px。此時(shí),clamp(100px, 50vw, 500px)相當(dāng)于clamp(100px, 600px, 500px),對(duì)應(yīng)的VAL值是600px,大于MAX值,那么這個(gè)時(shí)候clamp()函數(shù)返回的值是MAX,即500px,這個(gè)時(shí)候.element的width值就是500px(即MAX的值)。
如果我們把瀏覽器視窗縮小至760px:
這個(gè)時(shí)候.element元素的width是50vw。此時(shí),clamp(100px, 50vw, 500px)相當(dāng)于clamp(100px, 380px, 500px),對(duì)應(yīng)的VAL值是380px,該值大于MIN值(100px),小于MAX值(500px),那么這個(gè)時(shí)候clamp()函數(shù)返回的值是VAL,即50vw,這個(gè)時(shí)候.element的width值就是50vw(即VAL的值)。
如果繼續(xù)將瀏覽器的視窗縮小至170px:
這個(gè)時(shí)候.element元素的width是100px。此時(shí),clamp(100px, 50vw, 500px)相當(dāng)于clamp(100px, 85px, 500px),對(duì)應(yīng)的VAL值是85px,該值小于MIN值(100px),那么這個(gè)時(shí)候clamp()函數(shù)返回的值是MIN,即100px,這個(gè)時(shí)候.element的width值就是100px(即MIN的值)。
就該示例而言,clamp(100px, 50vw, 500px)還可以這樣來(lái)理解:
元素.element的寬度不會(huì)小于100px(有點(diǎn)類似于元素設(shè)置了min-width: 100px)
元素.element的寬度不會(huì)大于500px(有點(diǎn)類似于元素設(shè)置了max-width: 500px)
首選值VAL為50vw,只有當(dāng)視窗的寬度大于200px且小于1000px時(shí)才會(huì)有效,即元素.element的寬度為50vw(有點(diǎn)類似于元素設(shè)置了width:50vw)
具體效果如下占擊這里查看(https://codepen.io/airen/embed/pojVpJv)。
Logo圖標(biāo)的對(duì)齊
我想你在Web開(kāi)發(fā)中可能碰到過(guò)類似下圖的這樣的場(chǎng)景:
正像上圖所示,Logo圖像的有大有小(寬度和高度都不一樣)。面對(duì)這樣的業(yè)務(wù)場(chǎng)景,很多時(shí)候都希望設(shè)計(jì)師能提供相同尺寸的圖像。但這樣勢(shì)必會(huì)影響Logo圖像的外觀。
前段時(shí)間看到@Ahmad Shadeed專門寫(xiě)了一篇博文《Aligning Logo Images in CSS(//ishadeed.com/article/aligning-logos-css/)》,就是介紹如何實(shí)現(xiàn)上圖這樣的布局效果。
其實(shí)實(shí)現(xiàn)這樣的布局效果,主要運(yùn)用到的就是CSS的object-fit屬性,而這個(gè)屬性早在多年前就得到了各大主流瀏覽器的支持。
這里我們用一個(gè)簡(jiǎn)單的示例,來(lái)看看具體實(shí)現(xiàn)過(guò)程。先來(lái)看HTML結(jié)構(gòu):
<ul class="brands"> <li class="brands__item"> <a href="#"> <img src="img/logo.png" alt=""> a> li> <li> li>ul>居中對(duì)齊前面已經(jīng)介紹過(guò)了,這里主要是看圖像大小方面的處理:
.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)來(lái):
.brands__item img { width: 130px; height: 75px; object-fit: contain; mix-blend-mode: multiply;}這個(gè)時(shí)候,你看到的效果如下:
object-fit除了取值contain之外,還有其他幾個(gè)值,具體的可以看這個(gè)示例(https://codepen.io/airen/embed/VweXXoo):
其實(shí)這個(gè)方案也適用于產(chǎn)品圖片,人物頭像等布局。
小結(jié)
文章中主要介紹了Web中一些布局的實(shí)現(xiàn)思路和具體方案。其實(shí)文章提到的效果,比如水平垂直居中、等高布局、平均分布列和Sticky Footer等,在CSS中一直有多種解決方案,只不過(guò)隨著CSS Flexbox布局模塊和CSS Grid布局模塊的到來(lái),實(shí)現(xiàn)這些效果變得更為靈活和簡(jiǎn)潔。
當(dāng)然,文章中提到的只是一些最為常見(jiàn)一些效果,其實(shí)在Web布局中,特別是Flexbox布局和Grid布局中還存在很多有意思的東西,只不過(guò)因?yàn)槠臅r(shí)間沒(méi)有一一羅列。如果你感興趣可以再挖掘一些出來(lái),如果你在這方面有更好的經(jīng)驗(yàn)或方案,歡迎在下面的評(píng)論中分享。最后希望這篇文章對(duì)你平時(shí)的工作有所幫助。
???拓展閱讀作者|廖偉華(大貘)編輯|橙子君出品|阿里巴巴新零售淘系技術(shù)總結(jié)
以上是生活随笔為你收集整理的css布局方式_网页布局都有哪种?一般都用什么布局?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: wxpython 调用子窗口_wxpyt
- 下一篇: 怎么在电脑上任意截屏_草地上打滚、墙上任