僅20行CSS中的響應式網格雜誌佈局
最近我正在嘗試重新設計博客列表。想法是為讀者提供來自這些博客的最新文章,採用雜誌風格的佈局,而不是僅僅在側邊欄中列出我們最喜歡的博客。
輕鬆的部分是從我們最喜歡的RSS源中獲取包含摘要的文章列表。為此,我們使用了WordPress插件Feedzy lite,它可以將多個Feed聚合到一個按時間排序的列表中——非常適合展示它們的最新內容。困難的部分是讓它看起來很棒。
該插件的默認列表UI相當平淡無奇,所以我想將其樣式設計成類似報紙或雜誌網站,混合使用較小和較大的“特色內容”面板。
這似乎是CSS Grid的理想用例!為不同的佈局創建網格佈局,例如,一個五列佈局和一個三列佈局,然後使用媒體查詢在不同的斷點之間切換。對吧?但是,當我們可以使用網格的自動適應選項為我們自動創建一個流暢的響應式網格時,我們真的需要這些媒體查詢——以及識別斷點的所有麻煩嗎?
這種方法聽起來很有吸引力,但是當我開始引入跨列元素時,我遇到了網格在窄屏幕上溢出的問題。媒體查詢似乎是唯一解決方案。也就是說,直到我找到一個解決方法!
在查看了幾個關於CSS Grid的教程後,我發現它們主要分為兩類:
- 向您展示如何使用跨越元素創建有趣的佈局的教程,但列數是固定的。
- 解釋如何製作自動調整大小的響應式網格的教程,但所有網格項的寬度都相同(即沒有跨列)。
我想讓網格同時做到這兩點:創建一個完全響應式的流體佈局,其中還包括響應式調整大小的多列元素。
美妙之處在於,一旦您理解了響應式網格的局限性,以及為什麼以及何時列跨度會破壞網格響應性,就可以僅用十幾行代碼加上一個簡單的媒體查詢(或者如果您願意限制跨度選項,甚至無需媒體查詢)來定義響應式雜誌/新聞樣式佈局。
這是一個視覺效果,顯示了開箱即用的RSS插件以及我們對其進行樣式設置後的樣子。
此雜誌風格的網格佈局是完全響應式的,彩色特色面板會隨著列數的變化而動態調整。頁面顯示大約50篇文章,但佈局代碼與顯示的項目數量無關。將插件升級以顯示100個項目,佈局一直保持有趣。
所有這一切都只使用CSS實現,並且只有一個媒體查詢來處理最窄屏幕(即小於460像素)上的單列顯示。
令人難以置信的是,這個佈局只用了21行CSS代碼(不包括全局內容樣式)。但是,為了用這麼少的代碼行實現這種靈活性,我不得不深入研究CSS Grid的一些更晦澀的部分,並學習如何解決它的一些固有限制。
產生此佈局的代碼的基本元素非常短,證明了CSS Grid的強大功能:
<code>.archive { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); grid-gap: 32px; grid-auto-flow: dense; } /* 特宽网格文章*/ .article:nth-child(31n 1) { grid-column: 1 / -1; } .article:nth-child(16n 2) { grid-column: -3 / -1; } .article:nth-child(16n 10) { grid-column: 1 / -2; } /* 手机单列显示*/ @media (max-width: 459px) { .archive { display: flex; flex-direction: column; } }</code>
本文中的技術同樣可以很好地用於設置任何動態生成的內容,例如最新文章小部件、存檔頁面或搜索結果的輸出。
創建響應式網格
我設置了十七個項目,顯示各種模擬內容——標題、圖像和摘錄——它們都包含在一個包裝器中
<code><div> </div></code>
將這些項目轉換為響應式網格的代碼非常緊湊:
<code>.archive { /* 将元素定义为网格容器*/ display: grid; /* 自动适应尽可能多的项目在一行上,而不会低于180像素*/ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); /* 文章之间的一点间距*/ grid-gap: 1em; }</code>
請注意,行高會自動調整以適應行中最高的內容。如果您更改Pen的寬度,您將看到項目流暢地增長和縮小,列數分別從一列變為五列。
此處使用的CSS Grid魔法是auto-fit
關鍵字,它與應用於grid-template-columns
的minmax()
函數配合使用。
工作原理
我們可以僅使用以下方法實現五列佈局:
<code>.archive { display: grid; grid-template-columns: repeat(5, 1fr); }</code>
但是,這將創建五個列,這些列會隨著不同屏幕寬度的變化而增長和縮小,但始終保持五列,導致它們在小屏幕上變得非常窄。第一個想法可能是創建一堆媒體查詢並使用不同數量的列重新定義網格。這可以正常工作,但是使用auto-fit
關鍵字,所有這些都自動完成。
為了使auto-fit
按我們想要的方式工作,我們需要使用minmax()
函數。這告訴瀏覽器列可以壓縮到多小,然後是它們可以擴展到的最大寬度。更小,它將自動減少列數。更大,列數增加。
<code>.archive { grid-template-columns: repeat (auto-fit, minmax(180px, 1fr)); }</code>
在此示例中,瀏覽器將盡可能多地容納180像素寬的列。如果剩餘空間,列將通過在它們之間共享剩餘空間而平均增長——這就是1fr
值所說的:使列成為可用寬度的相等分數。
拖動窗口,隨著可用空間的增加,所有列都會平均增長以使用任何額外的空間。列將繼續增長,直到可用空間允許增加一列180像素,此時將出現一整列。減小屏幕寬度,該過程將反轉,完美地將網格調整到單列佈局。神奇!
而您只需一行代碼即可獲得所有這些響應能力。這有多酷?
使用“autoflow: dense”創建跨度
到目前為止,我們有一個響應式網格,但所有項目寬度都相同。對於新聞或雜誌佈局,我們需要一些內容通過跨越兩列或更多列甚至可能跨越所有列來突出顯示。
為了創建多列跨度,我們可以將column-span
功能添加到我們想要佔據更多空間的網格項目中。例如,如果我們希望列表中的第三個項目為兩列寬,我們可以添加:
<code>.article:nth-child(3) { grid-column: span 2; }</code>
但是,一旦我們開始添加跨度,就會出現許多問題。首先,網格中可能會出現間隙,因為寬項目可能無法適應行,因此網格自動適應將其推到下一行,留下它本來應該在的位置的間隙:
簡單的解決方法是向網格元素添加grid-auto-flow: dense
,這會告訴瀏覽器用其他項目填充任何間隙,有效地使較窄的內容圍繞較寬的項目流動,如下所示:
請注意,項目現在是無序的,第四個項目出現在雙倍寬度的第三個項目之前。據我所知,無法避免這種情況,這是您必須接受的CSS Grid的局限性之一。
查看Geoff Graham的“網格密集關鍵字的自動流動能力”,了解grid-auto-flow: dense
的介紹以及它如何運行的示例。
指定跨度的幾種方法
有幾種方法可以指示項目應跨越多少列。最簡單的方法是將grid-columns: span [n]
應用於其中一個項目,其中n是元素將跨越的列數。我們佈局中的第三個項目具有grid-column: span 2
,這解釋了為什麼它的寬度是僅跨越一列的其他項目的兩倍。
其他方法需要您顯式定義網格線。網格線的編號系統如下:
可以使用正值(例如1、2、3)或負值(例如-1、-2、-3)從左到右指定網格線,以從右到左進行。這些可用於使用grid-column
屬性在網格上放置項目,如下所示:
<code>.grid-item { grid-column: (起始轨道) / (结束轨道); }</code>
因此,這為我們提供了指定跨越項目的其他方法。這尤其靈活,因為起始值或結束值都可以替換為span
關鍵字。例如,上面示例中的三列藍色框可以通過向第八個網格項目添加以下任何內容來創建:
-
grid-column: 3 / 6
-
grid-column: -4 / -1
-
grid-column: 3 / span 3
-
grid-column: -4 / span 3
-
grid-column: span 3 / -1
- 等等
在非響應式(即固定列)網格上,所有這些都會產生相同的效果(如上圖中的藍色框),但是,如果網格是響應式的並且列數發生變化,它們的差異就會開始顯現。某些列跨度會破壞具有自動流動網格的佈局,使這兩種技術看起來不相容。幸運的是,有一些解決方案可以讓我們成功地將兩者結合起來。
但是,首先,我們需要了解問題。
溢出側滾動問題
以下是使用上述符號創建的一些特色區域:
在全寬(五列)時,一切看起來都很好,但當調整大小到應該是兩列時,佈局會像這樣中斷:
如您所見,我們的網格失去了響應能力,儘管容器已縮小,但網格試圖保持所有五列。為此,它放棄了嘗試保持等寬列,並且網格從其容器的右側溢出,導致水平滾動。
這是為什麼?問題是瀏覽器試圖遵守我們命名的顯式網格線。在這個寬度下,自動適應網格應該隱式地顯示兩列,但是我們的網格線編號系統通過顯式引用第五條網格線與之相矛盾。這種矛盾導致混亂。為了正確顯示我們隱式的兩列網格,唯一允許的行號是1、2和3以及-3、-2、-1,如下所示:
但是,如果我們的任何網格項目包含位於此範圍之外的grid-column
引用,例如網格線編號4、5或6(或-4、-5或-6),則瀏覽器會收到混合消息。一方面,我們要求它自動創建靈活的列(這應該隱式地為我們提供此屏幕寬度下的兩列),但我們還顯式地引用了在兩列網格中未出現的網格線。當隱式(自動)列和顯式列數之間存在衝突時,網格始終偏向於顯式網格;因此會出現不需要的列和水平溢出(這也恰當地被稱為CSS數據丟失)。就像使用網格線編號一樣,跨度也可以創建顯式列。因此, grid-column: span 3
(演示中的第八個網格項目)強製網格顯式採用至少三列,而我們希望它隱式顯示兩列。
在這一點上,似乎唯一前進的道路是使用媒體查詢在我們的佈局中斷的寬度處更改grid-column
值——但不要太快!這正是我一開始的假設。但是,在更仔細地考慮並嘗試各種選項之後,我發現有一些有限的解決方法可以一直向下工作到兩列,只留下一個媒體查詢來處理最窄屏幕上的單列佈局。
解決方案
我意識到,訣竅是只使用您打算顯示的最窄網格中出現的網格線來指定跨度。在這種情況下,是兩列網格。 (我們將使用媒體查詢來處理最窄屏幕上的單列場景。)這意味著我們可以安全地使用網格線1、2和3(或-3、-2和-1)而不會破壞網格。
我最初認為這意味著將自己限制在最多兩列的跨度,使用以下組合:
-
grid column: span 2
-
grid-column: 1 /3
-
grid-column: -3 / -1
這在一直到兩列的範圍內都保持完美的響應能力:
雖然這有效,但從設計的角度來看,它相當有限,而且不是特別令人興奮。我希望能夠創建在大型屏幕上為三列、四列甚至五列寬的跨度。但是怎樣呢?我的第一個想法是我必須求助於媒體查詢(天哪,舊習慣很難改!),但我試圖擺脫這種方法並以不同的方式思考響應式設計。
再次查看我們僅使用1到3和-3到-1可以做什麼,我逐漸意識到我可以混合使用網格列的起始值和結束值的正數和負數,例如1/-3和2/-2。乍一看,這似乎不是很令人感興趣。當您意識到這些線條在調整網格大小時的位置時,情況就會發生變化:這些跨越的元素會隨著屏幕大小的變化而改變寬度。這為響應式列跨度開闢了一整套新的可能性:隨著屏幕變寬,將跨越不同列數的項目,而無需媒體查詢。
我發現的第一個例子是grid-column: 1/-1
。這使得項目像一個全寬橫幅一樣,在所有列數下都從第一列跨越到最後一列。它甚至適用於一列寬!
通過使用grid-column: 1/-2
,可以創建一個左對齊的幾乎全寬跨度,它始終會在其右側留下一列項目。當縮小到兩列時,它會響應式地縮小到一列。令人驚訝的是,當縮小到單列佈局時,它甚至也能工作。 (原因似乎是網格不會將項目壓縮到零寬度,因此它保持一列寬, grid-column: 1/1
也是如此。)我假設grid-column: 2/-1
的工作方式類似,但與右側邊緣對齊,並且在大多數情況下確實如此,除了單列顯示時會導致溢出。
接下來我嘗試了1/-3
,它在較寬的屏幕上工作得很好,顯示至少三列,在較小的屏幕上顯示一列。我認為它在兩列網格上會做一些奇怪的事情,因為第一條網格線與-3的網格線相同。令我驚訝的是,它仍然作為單列項目正常顯示。
經過大量的嘗試,我找到了十一個可能的網格列值,使用了來自兩列網格的網格線編號。令人驚訝的是,其中三個一直到單列佈局都能正常工作。另外七個可以一直向下工作到兩列,只需要一個媒體查詢來處理單列顯示。
這是完整的列表:
如您所見,雖然這是所有可能的響應式跨度的有限子集,但實際上有很多可能性。
-
2/-2
很有趣,因為它創建了一個居中的跨度,一直到一列都能正常工作! -
3/-1
最沒用,因為它即使在兩列情況下也會導致溢出。 -
3/-3
是一個驚喜。
通過使用此列表中的各種grid-column
值,可以創建有趣且完全響應的佈局。對於最窄的單列顯示,使用單個媒體查詢,我們可以使用十種不同的網格列跨度模式。
單列媒體查詢通常也很簡單。此最終演示上的一個在較小的屏幕上恢復使用flexbox:
<code>@media (max-width: 680px) { .archive { display: flex; flex-direction: column; } .article { margin-bottom: 2em; } }</code>
這是最終網格,如您所見,它從一列到五列都是完全響應式的:
使用:nth-child() 重複可變長度顯示
我用來將代碼減少到二十幾行的最後一個技巧是:nth-child(n)
選擇器,我用它來設置網格中的多個項目樣式。我希望我的跨度樣式應用於我的Feed中的多個項目,以便特色帖子框定期出現在頁面中。首先,我使用了逗號分隔的選擇器列表,如下所示:
<code>.article:nth-child(2), .article:nth-child(18), .article:nth-child(34), .article:nth-child(50) { background-color: rgba(128,0,64,0.8); grid-column: -3 / -1; }</code>
但我很快發現這很麻煩,尤其是我必須為我想在每篇文章中設置樣式的每個子元素重複此列表——例如標題、鏈接等等。在原型設計期間,如果我想玩弄跨越元素的位置,我必須手動更改這些列表中的數字,這既費力又容易出錯。
那時我意識到我可以使用強大的功能:nth-child
偽選擇器,而不是像我在上面的列表中使用的那樣簡單的整數。 :nth-child(n)
也可以採用等式,例如:nth-child(2n 2)
,它將定位每個第二個子元素。
以下是如何使用:nth-child([公式])
在我的網格中創建藍色全寬麵板,這些面板出現在頁面的頂部,並在頁面下方重複出現:
<code>.article:nth-child(31n 1) { grid-column: 1 / -1; background: rgba(11, 111, 222, 0.5); }</code>
括號中的位(31n 1) 確保選擇第1個、第32個、第63個等子項。瀏覽器運行一個循環,從n=0開始(在這種情況下,31 0 1 = 1),然後是n=1(31 1 1 = 32),然後是n=2(31 * 2 1 = 63)。在最後一種情況下,瀏覽器意識到沒有第63個子項,因此它忽略該項,停止循環,並將CSS應用於第1個和第32個子項。
我對從右到左交替出現的紫色框做了類似的操作:
<code>.article:nth-child(16n 2) { grid-column: -3 / -1; background: rgba(128, 0, 64, 0.8); } .article:nth-child(16n 10) { grid-column: 1 / -2; background: rgba(128, 0, 64, 0.8); }</code>
第一個選擇器用於右側的紫色框。 16n 2 確保樣式應用於每第16個網格項目,從第二個項目開始。
第二個選擇器定位右側的框。它使用相同的間距(16n),但偏移量不同( 10)。結果,這些框會定期出現在第10、26、42等網格項目的右側。
當涉及到這些網格項目及其內容的視覺樣式時,我使用了另一個技巧來減少重複。對於兩個框共享的樣式(例如, background-color
),可以使用單個選擇器來定位兩者:
<code>.article:nth-child(8n 2) { background: rgba(128, 0, 64, 0.8); /* 其他共享样式*/ }</code>
這將定位項目2、10、18、26、34、42、50等等。換句話說,它選擇左右兩個特色框。
它之所以有效是因為8n 正好是16n 的一半,並且因為兩個單獨選擇器中使用的偏移量相差8(即10 和2 之間的差是8)
最後的想法
目前,CSS Grid 可用於使用最少的代碼創建靈活的響應式網格,但這確實對在不使用媒體查詢的倒退步驟的情況下定位元素有一些重要的限制。
能夠指定不會在較小屏幕上強制溢出的跨度會很棒。目前,我們實際上是告訴瀏覽器,“請創建一個響應式網格”,它做得非常漂亮。但是當我們繼續說,“哦,並且使這個網格項目跨越四列”時,它會在窄屏幕上發脾氣,優先考慮四列跨度請求而不是響應式網格。能夠告訴網格優先考慮響應能力而不是我們的跨度請求會很棒。類似這樣:
<code>.article { grid-column: span 3, autofit; }</code>
響應式網格的另一個問題是最後一行。隨著屏幕寬度的變化,最後一行經常不會被填充。我花了很長時間尋找一種方法來使最後一個網格項目跨越(並因此填充)剩餘的列,但目前看來您無法在Grid中做到這一點。如果我們可以使用像auto
這樣的關鍵字來指定項目的起始位置,那就太好了,這意味著“請將左邊緣放在它落下的任何位置”。類似這樣:
<code>.article { grid-column: auto, -1; }</code>
……這將使左邊緣跨越到行的末尾。
以上是僅20行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)

您是否曾經在項目上需要一個倒計時計時器?對於這樣的東西,可以自然訪問插件,但實際上更多

在元素個數不固定的情況下如何通過CSS選擇第一個指定類名的子元素在處理HTML結構時,常常會遇到元素個數不�...

關於Flex佈局中紫色斜線區域的疑問在使用Flex佈局時,你可能會遇到一些令人困惑的現象,比如在開發者工具(d...

格子呢是一塊圖案布,通常與蘇格蘭有關,尤其是他們時尚的蘇格蘭語。在Tartanify.com上,我們收集了5,000多個格子呢
