做者:Tim Vam Dammecss
讓咱們來看看一種超輕量級的方法,它能夠爲一組任意大小的照片建立水平磚砌效果。將任何照片丟到上面,它們將邊對邊無縫對齊。html
該解決方案不只輕巧,並且很是簡單。咱們將使用無序的圖片列表和僅僅17行CSS代碼,其中重點要領是flexbox和object-fit。瀏覽器
我有兩個業餘愛好:用照片記錄生活,以及找出新舊CSS屬性有趣的組合方式。app
幾周前,我參加了XOXO(注:XOXO是一個針對在線生活和工做的獨立藝術家的實驗性節日)而且拍攝了大量照片,而後我縮減爲39張照片。爲了擁有我本身的內容,我花了兩年的時間來組建一個簡單的照片博客,但始終沒法實現我想要的佈局:一個簡單的磚砌佈局,其中的照片填充行的同時要尊重其寬高比例(在iOS、Google Photos、Flickr上能夠考慮使用Photos.app)。ide
我進行了一些研究來查看是否有任何輕量級、非JavaScript的選項,可是不能找到適合我須要的任何內容。面對一些延誤的航班,我開始鼓搗一些代碼,限制本身儘量簡化事情(由於這是我對樂趣的定義)。佈局
因爲我基本上是在建立圖片列表,所以我選擇了無序列表:測試
<ul> <li> <img> </li> <!-- ... --> <li> <img> </li> </ul>
#全部像下冰雹同樣的彈性盒子flex
而後是一連串電燈泡時刻:優化
從理論上講,這聽起來是一個靠譜的計劃,這給了我90%滿意度的結果。ui
ul { display: flex; flex-wrap: wrap; } li { height: 40vh; flex-grow: 1; } img { max-height: 100%; min-width: 100%; object-fit: cover; vertical-align: bottom; }
注意:40vh彷佛是臺式機瀏覽器的最佳初始方式,以合理的大小顯示兩整行照片,並在下方顯示更多內容。這還容許每行更多照片,從而大大提升了寬高比例。
我遇到的惟一問題是flexbox確實想要填滿全部行,而且它對最後一行照片的長寬比作了一些蠢事。這多是這種佈局中我最不喜歡的一部分,可是我必須在列表的末尾添加一個空的<li>元素。
<ul> <li> <img> </li> <!-- ... --> <li> <img> </li> <li></li> </ul>
結合了這段CSS:
li:last-child { flex-grow: 10; }
注意:此處使用「10」是沒有科學依據的。在我全部的測試彙總,這提供了最佳結果。(注:做者的意思是這是一個測試結果中較佳的數字,是一個根據結果不斷調整後的嘗試值。)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name='viewport' content='width=device-width' /> <title></title> <style> ul { display: flex; flex-wrap: wrap; } li { height: 40vh; flex-grow: 1; list-style: none; } li:last-child { flex-grow: 10; } img { max-height: 100%; min-width: 100%; object-fit: cover; vertical-align: bottom; } @media (max-aspect-ratio: 1/1) { li { height: 30vh; } } @media (max-height: 480px) { li { height: 80vh; } } @media (max-aspect-ratio: 1/1) and (max-width: 480px) { ul { flex-direction: row; } li { height: auto; width: 100%; } img { width: 100%; max-height: 75vh; min-width: 0; } } </style> </head> <body> <ul> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05466_kwlv0n.jpg" alt="A Toyota Previa covered in graffiti" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05621_zgtcco.jpg" alt="Interesting living room light through a window" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05513_gfbiwi.jpg" alt="Sara on a red bike" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05588_nb0dma.jpg" alt="XOXO venue in between talks" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05459_ziuomy.jpg" alt="Trees lit by green light during dusk" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05586_oj8jfo.jpg" alt="Portrait of Justin Pervorse" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05465_dtkwef.jpg" alt="Empty bike racks outside a hotel" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05626_ytsf3j.jpg" alt="Heavy rain on an intersection" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05449_l9kukz.jpg" alt="Payam Rajabi eating peanut chicken" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05544_aczrb9.jpg" alt="Portland skyline sunset" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814785/photostream-photos/DSC05447_mvffor.jpg" alt="Interior at Nong's" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814784/photostream-photos/DSC05501_yirmq8.jpg" alt="A kimchi hotdog on a plate" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814784/photostream-photos/DSC05624_f5b2ud.jpg" alt="Restaurant window with graffiti saying 'water'" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814784/photostream-photos/DSC05623_dcpfva.jpg" alt="Portrait of Jeremy Tanner" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814784/photostream-photos/DSC05515_d2gzut.jpg" alt="Jordan, Sarah and Sara on red bikes, waiting" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814784/photostream-photos/DSC05581_ceocwv.jpg" alt="Barista wearing a hoodie saying 'Coffee Should Be Dope.'" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814784/photostream-photos/DSC05517_ni2k0p.jpg" alt="Payam crossing the street on a bike" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814783/photostream-photos/DSC05620_qfwycq.jpg" alt="Lit trees reflected in a puddle" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814783/photostream-photos/DSC05462_b33uvp.jpg" alt="Moody chair in my hotel room" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814783/photostream-photos/DSC05489_mqzktl.jpg" alt="Tom and Jenn wearing sunglasses" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814783/photostream-photos/DSC05476_dlkjza.jpg" alt="Jordan and Sarah in front of a restaurant window" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814783/photostream-photos/DSC05497_abbd3c.jpg" alt="Sarah reading the Double Dragon drink menu" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05487_fcdv7t.jpg" alt="Beer brewing equipment" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05493_q6njbk.jpg" alt="2 cocktails in the making" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05446_xj60ff.jpg" alt="Beverage fridge at Nong's" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05559_hu49zx.jpg" alt="Wood structure reflections" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05482_dtrj02.jpg" alt="Colorful garden equipment in a shop window" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05565_dx5rp6.jpg" alt="Sarah in front of a wooden wall" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05613_o9af2z.jpg" alt="A neon banana" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05469_fdxdzx.jpg" alt="Matt Sacks smiling while we're waiting for food" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814782/photostream-photos/DSC05558_yq2tnz.jpg" alt="A fixed-gear bike under some bright lights" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05483_dyiuya.jpg" alt="Panic's PlayDate being held by a tester" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05468_xzbtcd.jpg" alt="Window reflection of me and Payam" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05457_nloycw.jpg" alt="Upside down shopping carts" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05522_mekpec.jpg" alt="Payam riding a bike with no hands" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05611_lbwtmk.jpg" alt="A kid's pillow left on the bench of a bus stop" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05572_xfvij7.jpg" alt="My reflection in the mirror" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05481_gnljae.jpg" alt="Jordan holding an iced coffee against his head to cool down" loading="lazy"> </li> <li> <img src="https://res.cloudinary.com/css-tricks/image/upload/f_auto,q_auto/v1568814781/photostream-photos/DSC05480_zkw8sm.jpg" alt="Jordan and Sarah looking at the menu in a coffee shop" loading="lazy"> </li> <!-- Adding an empty <li> here so the final photo doesn't stretch like crazy. Try removing it and see what happens! --> <li></li> </ul> </body> </html>
在不一樣視口方向上進行操做時,須要牢記一些注意事項。
縱向排列
若是視口的高度大於寬度,則此方法會限制每行的照片數量,從而弄亂了它們的長寬比。 爲了解決這個問題,您可使用如下簡單的媒體查詢來下降照片行的高度:
@media (max-aspect-ratio: 1/1) { li { height: 30vh; } }
短屏
爲了幫助小型設備橫向排版美觀,須要增長照片的高度有助於使它們看起來儘量大:
@media (max-height: 480px) { li { height: 80vh; } }
較小屏幕+縱向排列
大多數手機的寬度不足以容許flexbox在不縮小照片尺寸的狀況下正常工做,所以在這裏我選擇不嘗試每行容納多張照片。 儘管如此,仍是值得在此處設置最大高度,所以您至少能夠提示列表中的下一張照片。
@media (max-aspect-ratio: 1/1) and (max-width: 480px) { ul { flex-direction: row; } li { height: auto; width: 100%; } img { width: 100%; max-height: 75vh; min-width: 0; } }
這種方法並未徹底尊重照片的長寬比(但很接近),偶爾會致使一些奇怪的結果,可是我絕對喜歡這一切的簡單性和靈活性。 想讓您的畫廊水平滾動而不是垂直滾動嗎? 進行一些調整可使您作到這一點。 畫廊中有1000張照片仍是隻有一張? 一切看起來都不錯。 不清楚縱橫比嗎? Flexbox是您最好的朋友。 若是尚未演示,請再看一下演示,讓我知道您的想法!
根據這些照片的大小,這樣的頁面可能很快就會增加到幾兆字節。 在我正在處理的博客上,我添加了loading =「 lazy」來幫助解決此問題。 在圖像上具備該屬性的狀況下,它僅在滾動時靠近照片時才加載照片。 目前,Chrome僅支持該功能,但您能夠採用本身更受支持的技術。
原文連接:
https://css-tricks.com/adaptive-photo-layout-with-flexbox/