很酷的小CSS網格技巧
十年前,我開始學習CSS,目的是修改自己博客的樣式。很快,我就能夠利用諸如transform之類的更具數學特性、更容易理解的功能來編寫炫酷的代碼。然而,CSS的其他領域,例如佈局,一直是我的痛點。
這篇文章講述的是我十年前遇到的一個問題,直到最近才找到一個巧妙的解決方案。具體來說,是關於我如何使用現代CSS Grid技術解決一個長期存在的問題,並且在這個過程中,得到了比我最初想像還要酷炫的結果。
需要注意的是,這不是一篇關於如何最佳使用CSS Grid的教程,而更像是我個人學習過程的記錄。
問題
我博客上最早發布的內容之一就是城市裡的隨機照片,所以我萌生了創建一個固定大小縮略圖網格的想法。為了美觀,我希望這個網格相對於上下的段落垂直居中對齊,但同時,我希望最後一行縮略圖相對於網格左對齊。與此同時,文章的寬度(以及其中網格的寬度)將取決於視口。
HTML代碼如下所示:
<p></p> <div class="grid--thumbs"> <a href="https://www.php.cn/link/19e321d9f307ccfc1c37106191cbbc74"> <img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174381745622040.jpg" class="lazy" alt="Cool Little CSS Grid Tricks for Your Blog"> </a> </div> <p></p>
看起來很簡單,但這卻成為我遇到的最棘手的CSS問題之一。
不理想的解決方案
這些是我多年來嘗試過或見過別人建議的方法,但都沒有真正解決問題。
浮動方案的局限性
浮動方案最終證明是死胡同,因為我無法弄清楚如何使網格以這種方式垂直居中對齊。
.grid--thumbs { overflow: hidden; } .grid--thumbs a { float: left; }
下面的演示展示了浮動方案的嘗試。調整嵌入的大小,看看它們在不同視口寬度下的表現。
inline-block 的不足
起初,這似乎是個更好的主意:
.grid--thumbs { text-align: center } .grid--thumbs a { display: inline-block }
但事實並非如此:
最後一行在這種情況下沒有左對齊。
在某個時候,由於CodePen上的意外CSS自動完成,我發現了名為text-align-last
的屬性,它決定塊的最後一行如何對齊。
不幸的是,在網格上設置text-align-last: left
也不是我想要的解決方案:
在這一點上,我實際上考慮放棄垂直居中網格的想法。 text-align: justified
和text-align-last: left
的組合能否在網格上產生更好的結果?
結果並非如此。除非最後一行只有一個縮略圖,並且列之間的間隙不太大。調整下面的嵌入大小,看看我的意思。
這幾乎就是兩年前我的處境,經過九年的嘗試和失敗,我仍然無法找到這個問題的解決方案。
凌亂的Flexbox技巧
一個一開始看起來可行的Flexbox解決方案是在網格上添加一個::after
偽元素,並在縮略圖和這個偽元素上設置flex: 1
:
.grid--thumbs { display: flex; flex-wrap: wrap; a, &::after { flex: 1; } img { margin: auto; } &:after { content: 'AFTER'; } }
下面的演示展示了這種方法是如何工作的。我已經為縮略圖和::after
偽元素添加了紫色邊框,以便更容易看出發生了什麼。
這並不是我想要的,因為縮略圖網格沒有垂直居中對齊。也就是說,只要最後一行比其他行少一個圖像,它看起來還不錯……一旦發生變化,如果缺少更多項目或沒有項目,佈局就會中斷。
這是一個很糟糕的想法。另一個方法是不使用偽元素,而是在縮略圖之後添加與我們期望擁有的列一樣多的空div。
我們應該能夠近似估計預期列數,因為縮略圖的大小是固定的,並且我們可能希望設置文章的最大寬度,因為跨越整個屏幕寬度的文本在視覺上會使眼睛疲勞。將最大寬度除以固定的縮略圖寬度應該會給出在這種情況下最大列數。
第一個空元素將佔據未完全填充縮略圖的行,其餘元素將溢出到其他行。但由於它們的高度為零,因此在視覺上無關緊要。
這種方法確實有效,但同樣,它很笨拙,並且仍然沒有產生我想要的確切結果,因為它有時會在列之間留下大而難看的間隙。
Grid 解決方案?
鑑於其名稱,網格佈局一直聽起來像是答案。問題是,我當時看到的所有示例都使用了預定義的列數,這對於這種特定模式不起作用,在這種模式下,列數由視口寬度確定。
去年,在編寫一系列單元素純CSS背景圖案時,我想到生成一堆媒體查詢,這些查詢將修改一個CSS變量--n
,該變量對應於用於設置grid-template-columns
的列數。
$w: 13em; $h: 19em; $f: $h/$w; $n: 7; $g: 1em; --h: #{$f*$w}; display: grid; grid-template-columns: repeat(var(--n, #{$n}), var(--w, #{$w})); grid-gap: $g; place-content: center; @for $i from 1 to $n { @media (max-width: ($n - $i 1)*$w ($n - $i 2)*$g) { --n: #{$n - $i} } }
當時我對這個想法非常自豪,儘管我現在回想起來覺得很尷尬。每個可能的列數一個媒體查詢並不是理想的,更不用說當網格寬度不等於視口寬度但仍然有點靈活並且還取決於其同級元素的寬度時,它也不太好用了。
魔幻般的解決方案
在使用CSS Grid並未能理解為什麼repeat()
函數在特定情況下不起作用時,我最終找到了一個更好的解決方案。這太令人沮喪了,促使我去MDN網站查看,我碰巧注意到了auto-fit
關鍵字,雖然我不理解解釋,但我有一種預感它可以幫助解決這個其他問題,所以我放棄了其他所有事情,嘗試了一下。
這就是我得到的:
.grid--thumbs { display: grid; justify-content: center; grid-gap: .25em; grid-template-columns: repeat(auto-fit, 8em); }
我還發現了minmax()
函數,它可以代替網格項目上的固定大小。我仍然無法完全理解minmax()
是如何工作的——我玩得越多,就越不理解它——但在這種情況下,它看起來像是創建網格,然後等比例拉伸其列,直到它們填滿所有可用空間:
grid-template-columns: repeat(auto-fit, minmax(8em, 1fr));
我們在這裡可以做的另一件很酷的事情是防止圖像在比網格元素更寬時溢出。我們可以通過將最小8em替換為min(8em, 100%)
來做到這一點。這基本上確保圖像永遠不會超過100%,但永遠不會低於8em。感謝Chris的建議!
請記住, min()
函數在Chromium之前的Edge中不起作用!
請記住,只有當所有圖像都具有相同的縱橫比(就像我在這裡使用的正方形圖像一樣)時,這才能產生良好的效果。對於我的博客來說,這不是問題,因為所有照片都是用我的索尼愛立信W800i手機拍攝的,它們都具有相同的縱橫比。但是,如果我們刪除具有不同縱橫比的圖像,網格看起來就不那麼好了:
當然,我們可以將圖像高度設置為固定值,但這會扭曲圖像……除非我們將object-fit
設置為cover
,這解決了我們的問題!
另一個想法是將第一個縮略圖變成一種跨越所有網格列的橫幅。唯一的問題是我們不知道列數,因為這取決於視口。但是,有一個解決方案——我們可以將grid-column-end
設置為-1!
.grid--thumbs { /* same styles as before */ a:first-child { grid-column: 1/ -1; img { height: 13em } } }
第一張圖片的高度比其他圖片都大。
當然,如果我們希望圖像跨越除最後一列之外的所有列,我們將將其設置為-2等等……負列索引是可以的!
auto-fill
是我在MDN上註意到的另一個網格屬性關鍵字。這兩個關鍵字的解釋都是長篇大論,沒有視覺效果,所以我發現它們並沒有什麼用。更糟糕的是,在上面的任何網格演示中將auto-fit
替換為auto-fill
都不會產生任何區別。即使查看文章或嘗試示例後,它們如何真正工作以及它們有何不同仍然是一個謎。
但是,嘗試不同的方法並在各種場景中查看結果,最終讓我得出結論:如果我們使用minmax()
列寬而不是固定列寬(例如8em),那麼最好使用auto-fill
而不是auto-fit
,因為如果我們只有幾張圖像,結果看起來會更好,如下面的交互式演示所示:
我認為我個人最喜歡的是最初的縮略圖網格的想法,它垂直居中對齊並且具有幾乎固定的列寬(但仍然使用min(100%, 15em)
而不是僅僅是15em)。歸根結底,這是一個個人喜好問題,在下面的演示中可以看到的內容恰好看起來對我來說更好:
我在這裡使用auto-fit
,因為它產生的結果與auto-fill
相同,並且字符更少。但是,我在製作這個時沒有理解的是,這兩個關鍵字產生相同的結果,因為圖庫中的項目比我們需要填充一行所需的更多。
但是一旦發生變化, auto-fit
和auto-fill
就會產生不同的結果,如下所示。您可以更改justify-content
值和放置在網格上的項目數量:
我不確定哪個是更好的選擇。我想這也取決於個人喜好。結合justify-content: center
, auto-fill
似乎是更合乎邏輯的選擇,但同時, auto-fit
會產生更好的視覺效果。
以上是很酷的小CSS網格技巧的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在本週的平台新聞綜述中,Chrome引入了一個用於加載的新屬性,Web開發人員的可訪問性規範以及BBC Move

有很多分析平台可幫助您跟踪網站上的訪問者和使用數據。也許最著名的是Google Analytics(廣泛使用)
