使用純 CSS 實(shí)現(xiàn) 500px 照片列表布局

使用純 CSS 實(shí)現(xiàn) 500px 照片列表布局

文章很長(zhǎng)柴信,因?yàn)榻榻B了如何一步一步進(jìn)化到最后接近完美的效果的咪鲜,不想讀的同學(xué)可以直接跳到最后一個(gè)大標(biāo)題之后看代碼关翎、demo 及原理就好橄登,或者也可以直接看下面這個(gè)鏈接的源代碼熬荆。不過(guò)還是建議順序讀下去,因?yàn)楹竺娴脑硇枰懊娴膬?nèi)容做為鋪墊兔甘,主要是在處理邊角問(wèn)題上谎碍。

先看下效果,要不然各位可能沒(méi)動(dòng)力讀下去了洞焙,實(shí)在是有點(diǎn)長(zhǎng)蟆淀,可以試著 resize 或者 zoom 一下看看動(dòng)態(tài)效果:Cats

PS:文中的一些 demo 為了方便展示源代碼用了 jsbin,但 jsbin 偶爾抽風(fēng)會(huì)顯示不出效果澡匪,試著在源代碼編輯框里不改變代碼意思的情況下編輯一下(比如在最后打一下回車(chē))應(yīng)該就可以了熔任,或者查看一下你瀏覽器的翻墻設(shè)置,因?yàn)槔锩嬉肓?Google CDN 上的文件唁情,有可能是因?yàn)?js 加載不成功導(dǎo)致的疑苔。

PS2:Demo 中用到的所有圖片都來(lái)自http://500px.com網(wǎng)站,圖片版權(quán)歸原作者所有荠瘪。圖片地址末尾的數(shù)字即為其在http://500px.com上的 id夯巷,如果你喜歡某張圖片,可以通過(guò)https://500px.com/photo/[id]/ 這個(gè)地址訪(fǎng)問(wèn)到圖片原始頁(yè)面哀墓。

好了趁餐,正文開(kāi)始。

開(kāi)始之前篮绰,先對(duì)比一下三種比較常見(jiàn)的圖片布局的差異

花瓣

此種布局為比較常見(jiàn)的等寬布局后雷,所有圖片的寬度是一樣的

由于圖片是等比拉伸(等比拉伸的意思是圖片的寬和高變化相同的比例,也就是圖片展示的寬高比與原始寬高比一致)吠各,而每張圖片的寬度又是一樣的臀突,所以圖片的高度就必然不一樣了

這種布局的缺點(diǎn)是,由于每張圖片展示的高度的不一致贾漏,圖片不是按一般的閱讀順序展示的候学,因?yàn)榭赡苓B續(xù)的多張圖片頂部的高度不一樣,而人眼又習(xí)慣于水平掃描纵散,所以用戶(hù)就有可能漏看某些照片

圖片瀑布的底部一般是對(duì)不齊的

雖然底部很難完全對(duì)齊梳码,但使用 JS 對(duì)圖片順序進(jìn)行重排能夠讓底部盡量對(duì)齊隐圾,所以此種布局在 reflow 的時(shí)候(比如resize,zoom)必然要有 JS 的參與

Google Photos掰茶,500px暇藏,圖蟲(chóng)等,以 Google Photos 為代表的即不等寬也不等高的圖片布局有如下特點(diǎn):

圖片也沒(méi)有被非等比拉伸

每行的圖片在水平方向上也占滿(mǎn)了屏幕濒蒋,沒(méi)有多余的空白

因?yàn)橐陨蟽蓚€(gè)條件盐碱,所以每行的圖片高度必然會(huì)不一樣,否則無(wú)法做到圖片在水平方向上占滿(mǎn)屏幕

圖片是按順序展示的沪伙,比較符合人眼閱讀順序瓮顽,Google Photos 因?yàn)檎掌信臄z時(shí)間這個(gè)屬性,必須滿(mǎn)足這個(gè)條件

底部是對(duì)齊的

Google Photos 的布局中焰坪,當(dāng)某幾個(gè)日期的照片太少時(shí)趣倾,多個(gè)日期的照片會(huì)合并展示在同一行聘惦,當(dāng)然這不是本文討論的重點(diǎn)

Instagram

正方形圖片布局某饰,就不多說(shuō)了~

以上介紹的前兩種布局都有一個(gè)共同點(diǎn),那就是圖片沒(méi)有經(jīng)過(guò)非等比拉伸善绎,也就是說(shuō)圖片里的內(nèi)容沒(méi)有變形黔漂,也沒(méi)有被裁剪,只是放大或者縮小禀酱,這是目前圖片類(lèi)應(yīng)用在展示圖片上的一個(gè)趨勢(shì)炬守,應(yīng)該說(shuō),很少有專(zhuān)做圖片的網(wǎng)站會(huì)把照片非等比拉伸顯示(變形拉伸真的給人一種殺馬特的感覺(jué)…)剂跟,最次的展示方式也就是把圖片裁剪成正方形后展示在一個(gè)正方形的區(qū)域里减途,類(lèi)似于正方形容器的 background-size: cover; 的效果。

另外曹洽,在花瓣的布局中鳍置,比較寬的圖片展示區(qū)域會(huì)比較小送淆;而在第二種布局中税产,則是比較高的圖片展示區(qū)域會(huì)比較小。

但是偷崩,在第一種布局中辟拷,因?yàn)閷挾仁嵌ㄋ懒说模愿邔挶刃〉揭欢ǔ潭鹊膱D片阐斜,顯示區(qū)域會(huì)非常小衫冻。而在第二種布局中,因?yàn)椴煌械母叨仁遣灰粯拥内顺觯绻容^高的圖片出現(xiàn)在比較高的行隅俘,還是有可能展示的稍大些的渡紫。

總體來(lái)說(shuō),以 Google Photos 為代表的圖片布局考赛,在顯示效果上更優(yōu)惕澎。關(guān)于如何使用 JS 來(lái)完成 Google Photos / 500px 布局的算法,這里就不討論了颜骤,讀者可以自己思考一下~

思考完成后可以看看這個(gè)頁(yè)面對(duì)這個(gè)布局的動(dòng)態(tài)演示唧喉,打開(kāi)頁(yè)面,等圖片全部加載完成后點(diǎn)擊頁(yè)面頂部的 layout 按鈕忍抽。

Demo 演示了如下的布局方式:先按照相同的高度把圖片排列起來(lái)八孝,然后按行對(duì)每行的圖片進(jìn)行等比放大,放大到當(dāng)前行的所有圖片正好跟容器兩邊對(duì)齊鸠项,布局完成干跛。

OK,下面根據(jù)上面的分析稍微總結(jié)一下評(píng)判圖片布局優(yōu)劣的一些標(biāo)準(zhǔn):

是否能盡量按原始列表中的順序輸出

能否按人眼的掃描順序輸出祟绊,即行高相同

圖片能否按照原始比例展示楼入,或者盡量按原始比例展示

每張圖片的展示面積能否盡量接近,實(shí)際上在想完全展示照片的布局中牧抽,這一條是很難達(dá)成的

圖片不被非等比拉伸嘉熊,內(nèi)容不變形,內(nèi)容展示完全

第一次看到類(lèi)似 Google Photos 照片列表的布局已經(jīng)不記得是在哪里了扬舒,當(dāng)時(shí)只是覺(jué)得這種布局肯定需要 JS 參與阐肤,因?yàn)槊啃袌D片高度相同的情況下不可能那么恰到好處的在容器兩端對(duì)齊,且所有圖片之間的間距大小也一樣(如果間距大小不一樣但兩端對(duì)齊讲坎,可以使用 inline 的圖片加上 text-justify 來(lái)實(shí)現(xiàn)孕惜,在圖片較小的時(shí)候(比如搜索引擎的圖片結(jié)果)也不失為一種選擇)。然而通過(guò)觀(guān)察晨炕,發(fā)現(xiàn)每行的高度并不相同衫画,就確認(rèn)了必然需要 JS 參與才能完成那樣的布局。

然而當(dāng)越來(lái)越多的開(kāi)始網(wǎng)站使用這樣的布局時(shí)府瞄,做為一個(gè)熱衷于能用 CSS 實(shí)現(xiàn)就不用 JS 的前端工程師碧磅,我就在考慮,能否僅用 CSS 實(shí)現(xiàn)這樣的布局呢遵馆?尤其是不要在 resize 時(shí)重新計(jì)算布局鲸郊。

在經(jīng)過(guò)一些嘗試后,我發(fā)現(xiàn)可在一定程度上用純 CSS 實(shí)現(xiàn)類(lèi)似的布局货邓。這里說(shuō)的一定程度上僅使用 CSS 實(shí)現(xiàn)布局秆撮,我的意思是:布局一但渲染完成,布局后序的 resize换况,zoom 都可以在沒(méi)有 JS 參與的情況下保持穩(wěn)定职辨,也就是說(shuō)盗蟆,首次的渲染甚至可以通過(guò)服務(wù)器完成,整個(gè)過(guò)程可以沒(méi)有 JS 參與舒裤,所以說(shuō)成是用純 CSS 實(shí)現(xiàn)也不過(guò)分喳资。

實(shí)現(xiàn)過(guò)程

下面就來(lái)介紹一下我是如何只通過(guò) CSS 一步一步實(shí)現(xiàn)的這個(gè)布局的:

一開(kāi)始,我們將圖片設(shè)置為相同的高度:

img{height:200px;}

這樣并不能讓圖片在水平方向上占滿(mǎn)窗口腾供,于是我想到了 flex-grow 這個(gè)屬性仆邓,讓 img 元素在水平方向變大占滿(mǎn)容器,整個(gè)布局也變成了 flex 的了:

div{display:flex;flex-wrap:wrap;}img{height:200px;flex-grow:1;}

把 flex container 的 flex-wrap 設(shè)置為 wrap伴鳖,這樣一行放不下時(shí)會(huì)自動(dòng)折行节值,每行的圖片因?yàn)?grow 的關(guān)系會(huì)在水平方向上占滿(mǎn)屏幕,效果看上去已經(jīng)很接近我們想要的了榜聂,但每張圖片都會(huì)有不同程度的非等比拉伸搞疗,圖片的內(nèi)容會(huì)變形,這個(gè)好辦须肆,可以用 object-fit: cover; 來(lái)解決匿乃,但這么一來(lái)圖片又會(huì)被裁剪一部分。

最終demo

注意圖片都被裁剪了休吠,尤其第一張扳埂。

不過(guò)上述的 DOM 結(jié)構(gòu)顯然是沒(méi)辦法在實(shí)際中使用的:

不支持 object-fit 的瀏覽器下圖片會(huì)變形,因?yàn)閳D片沒(méi)有容器瘤礁,所以也沒(méi)辦法用 background-size: cover; 來(lái)解決這個(gè)問(wèn)題

用了 object-fit 的瀏覽器下,圖片會(huì)被裁剪一部分梅尤,這兩條前面已經(jīng)說(shuō)過(guò)

沒(méi)辦法跟圖片一起展示一些相關(guān)的信息柜思,因?yàn)?img 是裸標(biāo)簽

另外就是在真實(shí)的網(wǎng)絡(luò)環(huán)境中,圖片的加載都是比較緩慢的巷燥,如果指望用圖片自己的尺寸來(lái)把布局撐開(kāi)赡盘,用戶(hù)肯定會(huì)看到非常多的閃爍,demo 里的閃爍應(yīng)該也已經(jīng)非常明顯了

所以我們上面的這個(gè)布局事實(shí)上是沒(méi)辦法用于任何生產(chǎn)環(huán)境的缰揪。

為 img 標(biāo)簽增加父元素

接下來(lái)我們把 DOM 結(jié)構(gòu)改成下面這樣的:

我們?yōu)閳D片增加了一個(gè)容器陨享。依然把圖片設(shè)置為定高,如此一來(lái)钝腺,每個(gè) div 將被圖片撐大抛姑,這時(shí)如果我們給 div 設(shè)置一個(gè) flex-grow: 1; ,每個(gè) div 將平分每行剩余的空間艳狐,div 會(huì)變寬定硝,于是圖片寬度并沒(méi)有占滿(mǎn) div。

如果我們將 img 的 width 設(shè)置為 100% 的話(huà)毫目,在 IE 和 Firefox 下蔬啡,div 已經(jīng) grow 的空間將不會(huì)重新分配(我覺(jué)得這是個(gè)很有意思的現(xiàn)象诲侮,圖片先把 div 撐大,div grow 之后又把圖片拉大)箱蟆,但在 Chrome 下沟绪,為 img 設(shè)置了 width: 100%; 之后,grow 的空間將被重新分配(我并沒(méi)有深究具體是如何重新分配的)空猜,重新分配后的結(jié)果是每個(gè)容器的寬度更加接近近零,這并不是我們想要的。

試了幾種樣式組合后抄肖,我發(fā)現(xiàn)把 img 標(biāo)簽的 min-width 和 max-width 都設(shè)置為 100% 的話(huà)久信,在 Chrome 下的顯示效果就跟 IE 和 Firefox 一樣了。最后我們將 img 的 object-fit 屬性設(shè)置為 cover漓摩,圖片就被等比拉伸并占滿(mǎn)容器了裙士,不過(guò)與前一種布局一樣,每行的高度是一樣的管毙,另外圖片只顯示了一部分腿椎,上下兩邊都被裁剪掉了一些。

上面布局完整的demo夭咬。

看起來(lái)跟前一個(gè)布局沒(méi)什么兩樣啃炸,但是現(xiàn)在我們可以在容器內(nèi)部加上一些額外的標(biāo)簽來(lái)顯示圖片信息了。

在這種布局下卓舵,如果圖片高度設(shè)置的比較小南用,布局已經(jīng)沒(méi)有什么大礙,因?yàn)閳D片越小就意味著每行的圖片越多而且剩余的空間越小并且剩余空間被更多的圖片瓜分掏湾,那每個(gè)容器的寬高比就越接近圖片的真實(shí)寬高比裹虫,多數(shù)圖片都能顯示出其主要部分。

棘手的最后一行

唯一的問(wèn)題是最后一行融击,當(dāng)最后一行圖片太少的時(shí)候筑公,比如只有一張,因?yàn)?grow 的關(guān)系尊浪,它將占滿(mǎn)一整行匣屡,而高度又只有我們?cè)O(shè)置的 200px,這時(shí)圖片被展示出來(lái)的部分可能是非常少的拇涤,更不用說(shuō)如果圖片本身上比較高捣作,而展示區(qū)域又比較寬的情況了。

針對(duì)這種情況工育,我們可以讓列表最后的幾張圖片不 grow虾宇,這樣就不至于出現(xiàn)太大的變形,我們可以算出每行的平均圖片數(shù)量如绸,然后用下面的 CSS 阻止“最后一行”的圖片 grow:

div:nth-last-child(5),div:nth-last-child(4),div:nth-last-child(3),div:nth-last-child(2),div:nth-last-child(1){flex-grow:0;}

然后配合 media query嘱朽,在屏幕不同寬度時(shí)旭贬,讓“最后一行”的元素個(gè)數(shù)在窗口寬度變化時(shí)也動(dòng)態(tài)變化:

@media(max-width:1000px)and(min-width:900px){div:nth-last-child(5),div:nth-last-child(4),div:nth-last-child(3),div:nth-last-child(2),div:nth-last-child(1){flex-grow:0;}}@media(max-width:1100px)and(min-width:1000px){div:nth-last-child(7),div:nth-last-child(6),div:nth-last-child(5),div:nth-last-child(4),div:nth-last-child(3),div:nth-last-child(2),div:nth-last-child(1){flex-grow:0;}}

上面的代碼寫(xiě)起來(lái)是相當(dāng)麻煩的,因?yàn)槊總€(gè)屏幕寬度范圍內(nèi)又要寫(xiě)多個(gè) nth-last-child 選擇器搪泳,雖然我們可以用預(yù)處理器來(lái)循環(huán)迭代出這些代碼稀轨,但最終生成出來(lái)的代碼還是有不少重復(fù)。

有沒(méi)有辦法只指定最后多少個(gè)元素就行了岸军,而不是寫(xiě)若干個(gè) nth-last-child 選擇器呢奋刽?其實(shí)辦法也是有的,想必大家應(yīng)該還記得 CSS 的 ~ 操作符吧艰赞,a ~ b 將選擇在 a 后面且跟 a 同輩的所有匹配 b 的元素佣谐,于是我們可以這么寫(xiě):

div:nth-last-child(8),div:nth-last-child(8) ~ div {? flex-grow: 0;}

先選中倒數(shù)第 8 個(gè)元素,然后選中倒數(shù)第 8 個(gè)元素后面的所有同輩結(jié)點(diǎn)方妖,這樣狭魂,就選中了最后的 8 個(gè)元素,進(jìn)一步党觅,我們可以直接將選擇器改寫(xiě)為 div:nth-last-child(9) ~ div雌澄,就可以只用一個(gè)選擇器選擇最后的 8 個(gè)元素了。

上面的幾種選擇尾部若干元素的不同選擇器杯瞻,實(shí)際上效果是不太一樣的:

div:nth-last-child(1),...,div:nth-last-child(n) 的選擇方法能保證倒數(shù)的 n 張圖片一定被選中镐牺,即使元素總個(gè)數(shù)不到 n

div:nth-last-child(n), div:nth-last-child(n) ~ div 只能保證當(dāng) div 元素至少有 n 個(gè)時(shí)才能選中最后的 n 個(gè)元素,因?yàn)槿绻?:nth-last-child(n) 不存在魁莉,這個(gè)選擇器就無(wú)效了

div:nth-last-child(n+1) ~ div 則需要保證 div 元素至少有 n+1 個(gè)時(shí)才能選中最后的 n 個(gè)元素睬涧,原理同上

選擇最后若干張圖片這種方式還是不夠完美,因?yàn)槟銦o(wú)法確定你選擇的 flex item 一定在最后一行沛厨,萬(wàn)一最后一行只有一張圖片呢宙地,這時(shí)倒數(shù)第二行的前幾張圖片就會(huì) grow 的很厲害(因?yàn)榈箶?shù)第二行的后面 n-1 張都不 grow),或者最后兩行圖片的數(shù)量都沒(méi)有這么多逆皮,那倒數(shù)第二行就沒(méi)有元素 grow 了,就占不滿(mǎn)這一行了参袱,布局就會(huì)錯(cuò)亂电谣。

那么有沒(méi)有辦法只讓最后一行的元素不 grow 呢?一開(kāi)始我也了很多方法抹蚀,甚至在想有沒(méi)有一個(gè) :last-line 偽類(lèi)什么的(因?yàn)橛袀€(gè) :first-line)剿牺,始終沒(méi)有找到能讓最后一行不 grow 的方法,然而最后竟然在搜索一個(gè)其它話(huà)題時(shí)找到了辦法:

那就是在最后一個(gè)元素的后面再加一個(gè)元素环壤,讓其 flex-grow 為一個(gè)非常大的值比如說(shuō) 999999999晒来,這樣最后一行的剩余空間就基本全被這一個(gè)元素的 grow 占掉了,其它元素相當(dāng)于沒(méi)有 grow郑现,更進(jìn)一步湃崩,我們可以用偽元素來(lái)做這件事(不過(guò) IE 瀏覽器的偽元素是不支持 Flexbox 屬性的荧降,所以還是得用一個(gè)真實(shí)的元素做 placeholder):

section::after{content:'';flex-grow:999999999;}

到這里,我們基本解決這個(gè)布局遇到的所有問(wèn)題攒读。

Demo朵诫,resize 或者 zoom 然后觀(guān)察最后一行的圖片。

現(xiàn)在這種布局下最后一行的圖片其實(shí)總是顯示完全且沒(méi)有拉伸和變形的薄扁。

但還有最后一個(gè)問(wèn)題剪返,同前一種布局一樣,如果你在線(xiàn)上去加載使用這種方式布局的網(wǎng)頁(yè)邓梅,你會(huì)發(fā)現(xiàn)頁(yè)面閃動(dòng)非常厲害脱盲,因?yàn)閳D片在下載之前是不知道寬高的,我們并不能指望圖片加載完成后讓它把容器撐大日缨,用戶(hù)會(huì)被閃瞎眼钱反。其實(shí)真正被閃瞎的可能是我們自己,畢竟開(kāi)發(fā)時(shí)要刷新一萬(wàn)零八百遍殿遂。

所以诈铛,我們必須預(yù)先渲染出圖片的展示區(qū)域(實(shí)際上幾乎所有圖片類(lèi)網(wǎng)站都是這么做的),所以這里還是要小用一些 js墨礁,這些工作也可以在服務(wù)器端做幢竹,或者是用任何一個(gè)模板引擎(下面的代碼使用了 angular 的模板語(yǔ)法)。

這個(gè)布局一旦吐出來(lái)恩静,后續(xù)對(duì)頁(yè)面所有的動(dòng)作(resize焕毫,zoom)都不會(huì)使布局錯(cuò)亂,同時(shí)也不需要 JS 參與驶乾,符合前文所說(shuō)的用純 CSS 實(shí)現(xiàn):

section{padding:2px;display:flex;flex-wrap:wrap;&::after{//處理最后一行content:'';flex-grow:999999999;}}div{margin:2px;position:relative;height:200px;flex-grow:1;background-color:violet;img{max-width:100%;min-width:100%;height:200px;object-fit:cover;vertical-align:bottom;}}// 下一行的**表達(dá)式**是計(jì)算當(dāng)圖片以 200 的高度等比拉伸展示時(shí)寬度的值

我們給圖片的父容器設(shè)置與圖片比例相同的初始大小邑飒,然后為它設(shè)置 flex-grow: 1; 等待它 grow,最終的效果將與上面種布局是一樣的级乐,但可以看到圖片在加載過(guò)程中布局是沒(méi)有抖動(dòng)的:

到這里疙咸,我們總算實(shí)現(xiàn)了圖片的非等寬布局。Demo风科,注意 HTML 模板里計(jì)算寬度的表達(dá)式撒轮。

那么這個(gè)布局的展示效果究竟如何呢?

實(shí)際上我專(zhuān)門(mén)寫(xiě)了代碼計(jì)算每張圖片被展示出來(lái)的比例到底有多少:在圖片高度為 150px 左右時(shí)贼穆,約有三分之一的圖片展示比例在 99% 以上题山。最差的圖片展示比例一般在 70% 左右浮動(dòng),平均每張圖片展示比例在 90% 以上故痊。圖片越矮/屏幕越大顶瞳,展示效果會(huì)越好;圖片越高/屏幕越小,展示效果就越差慨菱。

因?yàn)檫@種方案最后也被我拋棄了焰络,所以就不放計(jì)算展示比例的 demo 了。

看到這里抡柿,你應(yīng)該是覺(jué)得被坑了舔琅,因?yàn)檫@并沒(méi)有實(shí)現(xiàn)標(biāo)題中說(shuō)的 Google Photos / 500px 照片列表的布局

因?yàn)槊啃械母叨仁且粯拥模捅厝粚?dǎo)致大部分圖片沒(méi)有完全展示洲劣,跟 Google Photos / 500px 那些高大上的布局根本就不一樣备蚓!

其實(shí)正文從現(xiàn)在才正式開(kāi)始,下面介紹的方式也是我在實(shí)現(xiàn)了上面的布局后很久才想出來(lái)的囱稽,前面的內(nèi)容只是介紹一些解決邊角問(wèn)題用的郊尝。

可以看到,前面的實(shí)現(xiàn)方式并沒(méi)有讓每張圖片的內(nèi)容全部都顯示出來(lái)战惊,因?yàn)槊啃械母叨仁且粯拥牧骰瑁胍獙?shí)現(xiàn) 500px 的布局,每行圖片的高度很多時(shí)候是不一樣的吞获。

一開(kāi)始我覺(jué)得况凉,CSS 也就只能實(shí)現(xiàn)到這種程度了吧,直到我遇到了另一個(gè)需求:

我想用一個(gè)正方形的容器展示內(nèi)容各拷,并且希望無(wú)論瀏覽器窗口多寬刁绒,這些正方形的容器大小在一個(gè)范圍內(nèi)并且總是能鋪滿(mǎn)窗口的水平寬度而不留多余的空間(除了元素之間的空白),乍一看這個(gè)需求可能需要 JS 參與:讀出當(dāng)前瀏覽器窗口的寬度烤黍,然后計(jì)算正方形容器的 size知市,然后渲染。

可以看這個(gè)demo速蕊,試著拉動(dòng)一下窗口寬度然后看效果嫂丙。

拉動(dòng)過(guò)程中可以看到,正方形的容器會(huì)實(shí)時(shí)變大规哲,大到一定程度后又變小讓每行多出一個(gè)正方形容器跟啤。 如果只看這一個(gè) demo,可能各位不一定能一下子想到如何實(shí)現(xiàn)的唉锌,但如果只有一個(gè)正方形容器腥光,它的邊長(zhǎng)總是瀏覽器寬度的一半,想必很多人都知道的糊秆,長(zhǎng)寬比固定的容器要怎么實(shí)現(xiàn)吧?

我們知道(事實(shí)上很多人都不確定议双,所以這可以做為一個(gè)面試題)痘番,margin 和 padding 的值如果取為百分比的話(huà),這個(gè)百分比是相對(duì)于父元素的寬度的,也就是說(shuō)汞舱,如果我給一個(gè) block 元素設(shè)置 padding-bottom(當(dāng)然伍纫,也完全可以是 padding-top,甚至可以?xún)蓚€(gè)一起用)為 100% 的話(huà)昂芜,元素本身高度指定為 0莹规,那么這個(gè)元素將始終是一個(gè)正方形(因?yàn)樗母叨瓤偸歉?b>父元素的寬度一樣,而寬度 100% 也跟父元素的寬度一樣)泌神,并且會(huì)隨著容器寬度的變化而變化良漱,想要改變正方形的大小,只需要改變父容器的寬度就可以了:

看這個(gè)demo欢际,拉動(dòng)窗口可以看到色塊會(huì)變大母市,但始終保持正方形。當(dāng)然损趋,如果參照物是瀏覽器窗口患久,那么在現(xiàn)代瀏覽器中,這個(gè)效果可以用 vw / vh 實(shí)現(xiàn)浑槽;但如果參照物不是瀏覽器窗口屑墨,就只能用垂直 padding 來(lái)實(shí)現(xiàn)了话侄。

于是我就想到,如果不給 flex item 的元素設(shè)置高度,而是讓其被一個(gè)子元素?fù)伍_(kāi)刁标,并且這個(gè)子元素的寬度是100%,padding-bottom 也是 100%财异,那么 flex item 以及這個(gè)用來(lái)?yè)未蟾冈氐淖釉鼐蜁?huì)同時(shí)保持為正方形了劳跃,于是就實(shí)現(xiàn)了上面的那種正方形陣列布局。

但僅僅這樣還不夠邑闲,最后一行又會(huì)出問(wèn)題算行,如果最后一行的元素個(gè)數(shù)跟前面的行不一樣的話(huà),它們雖然會(huì)保持正方形苫耸,但是因?yàn)?grow 的關(guān)系州邢,會(huì)比較大,那如何保證最后一行的元素也跟前面的行大小相同呢褪子,這時(shí)使用一個(gè)元素并設(shè)置很大的 flex-grow 讓其占滿(mǎn)最后一行剩余空間的做法已經(jīng)不可行了量淌,因?yàn)槲覀冃枰屪詈笠恍械脑?b>恰到好處的跟前面行的元素 grow 時(shí)多出一樣的空間。

其實(shí)解決方案也很簡(jiǎn)單嫌褪,把最后一行不當(dāng)最后一行就行了呀枢!此話(huà)怎講呢?

在最后添加多個(gè)占位符笼痛,保證可見(jiàn)的最后一個(gè)元素永遠(yuǎn)處于視覺(jué)上的最后一行裙秋,而讓占位符占據(jù)真正的最后一行琅拌,然后把這些占位符的高度設(shè)置為 0 。具體添加多少個(gè)占位符呢摘刑?顯然是一行最多能顯示多少個(gè)元素进宝,就添加多少個(gè)了,比如前面的 demo 就添加了 8 個(gè)占位符枷恕,你可以在源代碼里面看一下党晋。另外為了更好的語(yǔ)義,其實(shí)可以用其它的標(biāo)簽當(dāng)做占位符徐块,這樣就不用寫(xiě)出上面那種晦澀的選擇器了未玻。

這樣一來(lái),始終能占滿(mǎn)水平寬度的正方形陣列布局也實(shí)現(xiàn)了蛹锰。

本來(lái)我以為深胳,到這里就結(jié)束了,即使用上最先進(jìn)的 Flexbox 布局铜犬,CSS 也無(wú)法實(shí)現(xiàn)圖片不裁減不拉伸且對(duì)齊的完美布局舞终。

- FAKE EOF -

4 月 2 號(hào)的早上我醒來(lái)的時(shí)候,突然想到癣猾,既然可以讓一個(gè)容器始終保持正方形敛劝,那豈不是也可以讓這個(gè)容器始終保持任何比例?顯然是可以的纷宇,只要我們把用于撐大父元素的那個(gè)元素的 padding-bottom 設(shè)置為一個(gè)我們想要的值就可以了夸盟!這樣一來(lái),說(shuō)不定可以實(shí)現(xiàn)圖片布局中像捶,所有圖片都完全展示且占滿(mǎn)水平寬度的布局(也就是 Google Photos / 500px 的布局)上陕!

當(dāng)然,前面提到過(guò)拓春,由于圖片加載緩慢释簿,圖片布局方案往往都會(huì)提前知道圖片的寬高來(lái)進(jìn)行容器的預(yù)渲染,然后圖片加載完成后直接放進(jìn)去硼莽。

所以這里我們?nèi)匀恍枰?JS 或者服務(wù)器來(lái)計(jì)算一下圖片的寬高比例庶溶,然后設(shè)置到 padding-bottom 上面去,以保證容器的寬高比始終是其內(nèi)部圖片的寬高比懂鸵。

我們先讓所有圖片以 200px 的高度展示偏螺,寫(xiě)出如下模板代碼:

這個(gè)公式計(jì)算了圖片高度為 200 時(shí)的寬度的值上面這個(gè)公式讓此元素及其父元素的比例與圖片原始比例相同,因?yàn)槭谴怪狈较虻?padding匆光,所以是高度除以寬度套像,又因?yàn)槭前俜直龋猿?100

在上面布局中终息,因?yàn)?flex-wrap 的關(guān)系凉夯,每一行不夠放的時(shí)候后面的內(nèi)容就會(huì)折行货葬,并且留出一些空白,每個(gè)容器的寬高比都是跟未來(lái)放入其內(nèi)部的圖片的寬高比是一樣的劲够,為了便于展示,我將圖片大小設(shè)置為容器大小的四分之一休傍,應(yīng)該明顯可以看出圖片的右下角處于容器的中心位置征绎。

Demo

下一步,我們只需要讓所有的容器元素都 grow 就可以了磨取,那么是把所有的元素的 flex-grow 設(shè)置為 1 嗎?

實(shí)際上如果設(shè)置了并看了效果人柿,我們會(huì)發(fā)現(xiàn)并不是,因?yàn)槲覀兿M啃性卦?grow 的時(shí)候忙厌,保持原有比例且高度相同凫岖。

Demo

可以看到如果給所有的 flex item 設(shè)置 flex-grow: 1; 的話(huà),容器跟圖片的比例并不一致(雖然比較接近)逢净,這里我將圖片寬度設(shè)置了為容器的寬度以便觀(guān)察哥放。

通過(guò)一些簡(jiǎn)單的計(jì)算我們會(huì)發(fā)現(xiàn),在每行的圖片中爹土,每張圖片在水平方向上占用的寬度正好是其寬度在這一行所有圖片寬度之和中所占的比例甥雕。

在前面不 grow 的情況下,每張圖片的容器的寬度已經(jīng)是按比例分配了胀茵,而想要實(shí)現(xiàn)前一行描述的分配方式社露,每行的剩余空間,我們希望它仍然按照目前容器寬度所占的比例來(lái)分配琼娘,于是峭弟,每個(gè)容器的 grow 的值,正好就是它的寬度脱拼,只不過(guò)不要 px 這個(gè)單位瞒瘸。

最終的代碼如下:

flex,wrap? //實(shí)際上因?yàn)?flex-grow 是按比例分配挪拟,所以第二個(gè)公式里的 *200 可以不要挨务,這要我們就只需要改前一個(gè) 200 了?



這樣一來(lái),容器會(huì)占滿(mǎn)當(dāng)前行玉组,并且保持與未來(lái)內(nèi)部所放入的圖片相同的寬高比:

Demo谎柄,可以看到,每張圖片都被完整展示出來(lái)了:

至于最后一行怎么處理惯雳,前面已經(jīng)介紹過(guò)了朝巫,用一個(gè) flex-grow 極大的元素占滿(mǎn)剩余空間就可以了。

這種布局在渲染完成后石景,你可以放心的 resize 和 zoom劈猿,布局都不會(huì)錯(cuò)亂拙吉,而且沒(méi)有 JS 的參與。

到這里揪荣,我們終于實(shí)現(xiàn)了類(lèi)似 Google Photos / 500px 網(wǎng)站的圖片布局筷黔。

總結(jié)一下這個(gè)方案的原理

padding(以及 margin)為百分比時(shí)是以容器的寬度為參照的

使用 flex-grow 來(lái)按圖片寬度所占的比例分配水平空間

使用寬高比固定的子元素?fù)未髱в兄付ū壤?flex-grow 的 flex item 以實(shí)現(xiàn)不同行高度不一樣并保持寬高比

這種布局的優(yōu)點(diǎn):

不需要特殊的算法去計(jì)算每張圖片渲染之后的寬高等信息

不需要在 resize,room 時(shí)重新計(jì)算布局

CSS 的方案容易跟任何框架集成

最后說(shuō)一下這種方案的一些缺點(diǎn):

很明顯仗颈,我們只能指定每行圖片的最低高度佛舱,然后等著它 grow,并沒(méi)有辦法指定每行高度的上限是多少挨决。雖然我們可以設(shè)置一下容器的 max-height请祖,這樣一來(lái)被 max-height 影響的那些容器里面的圖片就展示不完全了。實(shí)際上只要圖片的比例都在一個(gè)正常的范圍脖祈,是不會(huì)出現(xiàn)某一行的高度過(guò)高的

在遇到比例超出某個(gè)范圍的圖片時(shí)可以只用我們?cè)试S的最大比例展示這張圖片肆捕,比如說(shuō)遇到了一張 1:5 的圖片,我們只以 1:3 的區(qū)域來(lái)展示它盖高∩髁辏或者也可以調(diào)整一下圖片的順序,但這就需要 JS 參與了或舞。500px 的這個(gè)搜索結(jié)果頁(yè)面貌似就是這么做的荆姆,試著把窗口寬度調(diào)小,會(huì)發(fā)現(xiàn)第一張后面的圖片展示不完全映凳,因?yàn)槿绻故就耆脑?huà)胆筒,單張圖片就占用了太大的屏幕面積,所以它限定了高度诈豌。

另外仆救,最后一行的圖片如果幾乎要占滿(mǎn)那一行時(shí),因?yàn)檎嘉环拇嬖诮糜妫⒉粫?huì)占滿(mǎn)彤蔽,會(huì)顯得不太理想(讀者可以調(diào)整窗口寬度觀(guān)察上面的完整 demo)。這種情況如果是使用 JS 計(jì)算的話(huà)庙洼,是可以避免的:在發(fā)現(xiàn)最后一行幾乎要占滿(mǎn)時(shí)顿痪,直接讓其占滿(mǎn)最后一行。其實(shí)這個(gè)情況在后來(lái)我也想到了解決方案油够,即還是在最后放上占位符蚁袭,各位可以查看文章最開(kāi)始的 demo 中的源代碼就知道了,如果不理解石咬,可以留言討論揩悄。

我們?cè)谔岬皆u(píng)價(jià)圖片布局優(yōu)劣的標(biāo)準(zhǔn)時(shí)候說(shuō)到,每張圖片展示區(qū)域越接近鬼悠,評(píng)分應(yīng)該也越高删性。理論上如果使用 JS 來(lái)計(jì)算布局亏娜,可以在算法上做如下優(yōu)化:如果一行中比較高的圖片比較多,那么這一行就少放些圖片蹬挺,留出更多的空間用來(lái)放大圖片维贺,這樣就能讓高圖和寬圖顯示面積更接近一些了。而用 CSS 的方案如果不改變圖片順序就沒(méi)法做這種優(yōu)化了汗侵。不過(guò)如果不改變圖片順序幸缕,即使算法做了這些優(yōu)化,出現(xiàn)在高圖比較多的行里的寬圖晰韵,展示面積會(huì)更大,會(huì)出現(xiàn)一種比例失調(diào)的情況熟妓,也不夠完美雪猪。

關(guān)于降級(jí)

由于 IE 9 都是不支持 Flexbox 的,所以這個(gè)方案必然需要優(yōu)雅降級(jí)起愈。在不支持的瀏覽器上只恨,讓圖片都以正方形展示應(yīng)該也不會(huì)太差,然后用 float 或者 inline-block 來(lái)折行抬虽,這里就不細(xì)說(shuō)了官觅。

最后,本文其實(shí)只實(shí)現(xiàn)了 500px 的圖片的布局(即所有圖片在一個(gè)容器里)阐污,實(shí)際上并沒(méi)有實(shí)現(xiàn) Google Photos 的布局休涤,Google Photos 的布局比 500px 的還要復(fù)雜很多,仔細(xì)觀(guān)察就會(huì)發(fā)現(xiàn)笛辟,其是按日期排列并且不同日期在同一行顯示的時(shí)候也可以兩邊對(duì)齊功氨,這種布局后來(lái)我也有了純 CSS 的解決方案。如果各位意猶未盡手幢,可以在文后留言捷凄,我會(huì)將實(shí)現(xiàn)方案再整理一篇文章出來(lái)~

本文到此結(jié)束,謝謝圍觀(guān)围来!文中如有紕漏之處跺涤,還請(qǐng)各位大神留言指正~

最后的最后,廣告時(shí)間:

本人決定創(chuàng)業(yè)開(kāi)辦前端培訓(xùn)班监透,地點(diǎn)杭州桶错,9月20左右開(kāi)課,費(fèi)用優(yōu)惠包住宿才漆,詳情請(qǐng)點(diǎn)擊我的專(zhuān)欄文章:大喵教育前端培訓(xùn) - 介紹牛曹,如果有朋友想學(xué),歡迎介紹醇滥。如果沒(méi)有也希望你能進(jìn)去點(diǎn)個(gè)贊讓更多人看到~寫(xiě)文章不易黎比,創(chuàng)業(yè)更不易~先行謝過(guò)了超营!

我叫謝然,貓奴阅虫,網(wǎng)名充電大喵演闭,曾先后就職于省重點(diǎn)高中、阿里巴巴颓帝、小米米碰。2016 年 9 月離開(kāi)小米創(chuàng)建了自己的前端培訓(xùn)品牌“大喵教育前端培訓(xùn)”,第一期班于 2016 年 9 月 22 日順利開(kāi)班购城,目前課程一切順利吕座;第二期班將于 2017 年 3 月中旬開(kāi)課,地點(diǎn)杭州下沙瘪板。大喵教育前端培訓(xùn)勵(lì)志辦靠譜的前端培訓(xùn)吴趴,重視基礎(chǔ),開(kāi)設(shè)算法侮攀、數(shù)據(jù)結(jié)構(gòu)锣枝、計(jì)算機(jī)網(wǎng)絡(luò)等相關(guān)課程,并且部分課程使用英文授課兰英,我的目標(biāo)就是利用自己的專(zhuān)業(yè)技術(shù)在五個(gè)月的時(shí)間內(nèi)踏踏實(shí)實(shí)的把該教的內(nèi)容教給學(xué)員撇叁,不坑爹,不造假畦贸。如果你有興趣了解陨闹,請(qǐng)點(diǎn)擊:大喵教育前端培訓(xùn) - 介紹

「真誠(chéng)贊賞家制,手留余香」

2人贊賞了4

CSS 布局500pxGoogle 相冊(cè)

383

收藏

分享

編輯

文章被以下專(zhuān)欄收錄

前端雜貨鋪

關(guān)注前端正林,不浮躁,不迂腐颤殴,踏踏實(shí)實(shí)觅廓。

進(jìn)入專(zhuān)欄

前端外刊評(píng)論

關(guān)注前端前沿技術(shù),探尋業(yè)界深邃思想 qianduan.guru

進(jìn)入專(zhuān)欄

49 條評(píng)論

寫(xiě)下你的評(píng)論...

沈振宇

我是圖蟲(chóng)的創(chuàng)始人涵但,有興趣可以知乎私信聊一下

1 年前

查看對(duì)話(huà)

謝然(作者)回復(fù)沈振宇

搬知乎來(lái)半個(gè)月杈绸,終于有了第一條評(píng)論,沒(méi)想到竟然是…我私信你…

6贊

1 年前

木亦

css魔法矮瘟。瞳脓。。

1 年前

Zimmer

馬克一下

1 年前

Zimmer

馬克一下

1 年前

孫飛

寫(xiě)的真好澈侠!劫侧,希望出下一篇文章

1 年前

查看對(duì)話(huà)

謝然(作者)回復(fù)孫飛

會(huì)的~

1 年前

辛?xí)r雨

純 CSS 我們?cè)趺茨懿蛔檀?/p>

2贊

1 年前

learnshare

Instangram -> Instagram :)

1 年前

張曉樣

辛苦

1 年前

12345下一頁(yè)

推薦閱讀

阿斯塔納:世博會(huì)開(kāi)幕,就在這座草原上崛起的超現(xiàn)實(shí)主義之城

我們?cè)谌粘鲋畷r(shí)抵達(dá)阿斯塔納,初升的太陽(yáng)照耀在一望無(wú)際的大平原上烧栋,視野中的天際線(xiàn)浮現(xiàn)出一…查看全文

Luna Li

1 個(gè)月前

編輯精選發(fā)表于兩個(gè)瘋子的亞歐見(jiàn)聞

撤銷(xiāo)企業(yè)登記等行政許可写妥,是糾正違法行為,不屬行政處罰审姓!

撤銷(xiāo)企業(yè)登記等行政許可珍特,是糾正違法行為,不屬行政處罰魔吐! 黃璞琳 (歡迎點(diǎn)擊訂閱“璞琳說(shuō)…查看全文

黃璞琳

1 個(gè)月前

編輯精選發(fā)表于璞琳說(shuō)法

汽車(chē)品牌相愛(ài)相殺扎筒,多年前他們都是一家人,今天我們聊保時(shí)捷和戴姆勒

克萊斯勒的創(chuàng)始人曾經(jīng)是別克品牌的總經(jīng)理酬姆;戴姆勒創(chuàng)世人的兒子保羅戴姆勒曾經(jīng)是奧迪(Horch…查看全文

王洪浩

13 天前

編輯精選

探路二次元|在荊棘坎坷中成長(zhǎng)的中國(guó)配音演員

本文由 @ 微博動(dòng)漫 授權(quán)轉(zhuǎn)載嗜桌。序 近幾年,隨著國(guó)產(chǎn)動(dòng)畫(huà)關(guān)注度的提高辞色,諸如“《狐妖小紅娘》…查看全文

下水道撈魚(yú)小分隊(duì)

1 個(gè)月前

編輯精選發(fā)表于隊(duì)長(zhǎng)的撈魚(yú)筆記

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末症脂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子淫僻,更是在濱河造成了極大的恐慌,老刑警劉巖壶唤,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雳灵,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡闸盔,警方通過(guò)查閱死者的電腦和手機(jī)悯辙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)迎吵,“玉大人躲撰,你說(shuō)我怎么就攤上這事』鞣眩” “怎么了拢蛋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)蔫巩。 經(jīng)常有香客問(wèn)我谆棱,道長(zhǎng),這世上最難降的妖魔是什么圆仔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任垃瞧,我火速辦了婚禮,結(jié)果婚禮上坪郭,老公的妹妹穿的比我還像新娘个从。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布嗦锐。 她就那樣靜靜地躺著嫌松,像睡著了一般。 火紅的嫁衣襯著肌膚如雪意推。 梳的紋絲不亂的頭發(fā)上豆瘫,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音菊值,去河邊找鬼外驱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛腻窒,可吹牛的內(nèi)容都是我干的昵宇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼儿子,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瓦哎!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起柔逼,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蒋譬,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后愉适,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體犯助,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年维咸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了剂买。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡癌蓖,死狀恐怖瞬哼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情租副,我是刑警寧澤坐慰,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站附井,受9級(jí)特大地震影響讨越,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜永毅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一把跨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沼死,春花似錦着逐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)健芭。三九已至,卻和暖如春秀姐,著一層夾襖步出監(jiān)牢的瞬間慈迈,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工省有, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痒留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓蠢沿,卻偏偏與公主長(zhǎng)得像伸头,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舷蟀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案恤磷? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,754評(píng)論 1 92
  • H5移動(dòng)端知識(shí)點(diǎn)總結(jié) 閱讀目錄 移動(dòng)開(kāi)發(fā)基本知識(shí)點(diǎn) calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇閱讀 4,508評(píng)論 0 26
  • 移動(dòng)開(kāi)發(fā)基本知識(shí)點(diǎn) 一.使用rem作為單位 html { font-size: 100px; } @media(m...
    橫沖直撞666閱讀 3,475評(píng)論 0 6
  • CSS 3中彈性盒布局的最新版概述 在CSS 3中,CSS Flexible Box模塊為一個(gè)非常重要的模塊野宜,該模...
    吾名無(wú)雙閱讀 1,232評(píng)論 0 5
  • 前言 溫馨提示:本文較長(zhǎng)扫步,圖片較多,本來(lái)是想寫(xiě)一篇 CSS 布局方式的匈子,但是奈何 CSS 布局方式種類(lèi)太多并且實(shí)現(xiàn)...
    sunshine小小倩閱讀 3,139評(píng)論 0 59