翻譯:瘋狂的技術宅javascript
原文:css-tricks.com/using-the-g…css
未經許可,禁止轉載!html
牧羊人很擅長照顧他們的羊羣,爲牧羣帶來秩序和結構。即便有幾百只毛茸茸的動物,牧羊人仍然會在一天結束時將它們悉數帶回農場。前端
而對於程序員來講,當咱們在處理數據時,一般不知道這些數據是否已經被正確的過濾或者排序。尤爲是當你想要在頁面上按照稍微複雜一點的規則顯示數據時,這就比較痛苦了。 Grid Shepherd 是一種使用 CSS Grid 幫助定位和排序的技術,徹底不須要 JavaScript 的參與。java
這就是本文要解決的問題。 Grid Shepherd 技術能夠爲咱們的數據提供所需的順序和結構,讓咱們更好地瞭解它的使用方式和應用場景。程序員
讓咱們來深刻研究一下。web
咱們首先針對農場中一系列無序的動物進行排序。想象一下牛和羊在農場中清閒的樣子。咱們能夠用 Array.prototype.sort
方法以編程方式對其排序分組並展現在頁面上:編程
let animals = [
{ name: 'Edna', animal: 'cow' },
{ name: 'Liam', animal: 'sheep' },
{ name: 'Fink', animal: 'sheep' },
{ name: 'Olga', animal: 'cow' },
]
let sortedAnimals = animals.sort((a, b) => {
if (a.animal < b.animal) return -1
if (a.animal > b.animal) return 1
return 0
})
console.log(sortedAnimals)
/* Returns: [ { name: 'Elga', animal: 'cow' }, { name: 'Olga', animal: 'cow' }, { name: 'Liam', animal: 'sheep' }, { name: 'Fink', animal: 'sheep' } ] */
複製代碼
Grid Shepherd 方法可以在不依賴 JavaScript 的狀況下實現對數據的排序,只依靠 CSS Grid 自己就能夠作到。前端工程化
下面的結構與上面的 JavaScript 對象數組徹底相同,只不過是在 DOM 節點中表示的。數組
<main>
<div class="cow">Edna</div>
<div class="sheep">Liam</div>
<div class="sheep">Jenn</div>
<div class="cow">Fink</div>
</main>
複製代碼
CodePen上的演示:codepen.io/Achilles_2/…
爲了放養這些動物,咱們必須將它們圍在一個公共區域內,這就是咱們 <main>
元素要作的事。經過使用 display:grid
設置該柵欄,咱們建立了一個網格格式化上下文,能夠在其中定義每種動物應該佔據的列(或行)。
.sheep { grid-column: 1; }
.cow { grid-column: 2; }
複製代碼
經過 grid-auto-flow:dense
,每隻動物都會讓本身進入對應定義區域的第一個可用點。也能夠用於任意數量的不一樣排序規則—— 只需再定義另外一個列,數據就會被神奇地引導到其中。
main
display: grid;
grid-auto-flow: dense;
}
.sheep { grid-column: 1; }
.cow { grid-column: 2; }
複製代碼
CodePen:codepen.io/Achilles_2/…
咱們還能夠經過 CSS Counters 進一步豐富這個例子。這樣咱們能夠計算每一列中有多少隻動物,並根據這個數量來有條件地設置它們的樣式。
數量查詢依賴於某種類型的選擇器來計算其數量 —— 這對於僞類表示法 :nth-child(An+B [of S\ ]?)
來講會很好。但它目前僅在 Safari 中可用。這意味着咱們必須用 :nth-of-type()
選擇器來解決這個問題。
咱們須要一些新的元素類型才能實現。這能夠經過 Web 組件實現,也能夠將 HTML 元素重命名爲自定義名稱。即便這些元素不在 HTML 規範中,也一樣適用,由於瀏覽器對未定義的標記使用 HTMLUnknownElement
,這會致使他們的表現很像一個div。該文檔如今看起來像這樣:
<fence>
<sheep>Lisa</sheep>
<sheep>Bonnie</sheep>
<cow>Olaf</cow>
<sheep>Jenn</sheep>
</fence>
複製代碼
如今咱們能夠訪問本身的自定義元素類型了。當羊或牛的數量小於等於 10 時應用紅色背景。
sheep:nth-last-of-type(n+10),
sheep:nth-last-of-type(n+10) ~ sheep,
cow:nth-last-of-type(n+10),
cow:nth-last-of-type(n+10) ~ cow, {
background-color: red;
}
複製代碼
能夠經過在父元素上使用 counter-reset:countsheep countcow;
並使用 before
選擇器來定位每一個元素並計數,這樣就實現了一個簡單的計數器。
sheep::before {
counter-increment: countsheep;
content: counter(countsheep);
}
複製代碼
你能夠經過下面這個演示觀察在不一樣的排序規則下,對動物進行添加和移除時的效果:
CodePen演示:codepen.io/Achilles_2/…
Grid Shepherd 還能夠和任何非有序數據一塊兒使用:
grid-auto-flow:dense
不會改變網格的 DOM 結構 —— 它只是在視覺上對包含的元素從新排序。最後一個例子中會看到反作用:按字母順序排序時, counter
的數字被混淆了。更改 DOM 結構不只會影響使用屏幕閱讀器的用戶,還會影響對標籤遍歷的效果。
本文描述瞭如何將一個功能強大的 CSS 佈局工具(如grid)用於不符合傳統佈局需求的案例。咱們能夠看到 CSS Grid 的佈局優點和 JavaScript 的動態數據處理功能是重疊的,它能夠爲咱們提供更多的選擇和功能,是咱們可以爲所欲爲的去渲染數據。