用CSS Grid Shepherd 技術對數據進行排序

翻譯:瘋狂的技術宅javascript

原文:css-tricks.com/using-the-g…css

未經許可,禁止轉載!html

牧羊人很擅長照顧他們的羊羣,爲牧羣帶來秩序和結構。即便有幾百只毛茸茸的動物,牧羊人仍然會在一天結束時將它們悉數帶回農場。前端

而對於程序員來講,當咱們在處理數據時,一般不知道這些數據是否已經被正確的過濾或者排序。尤爲是當你想要在頁面上按照稍微複雜一點的規則顯示數據時,這就比較痛苦了。 Grid Shepherd 是一種使用 CSS Grid 幫助定位和排序的技術,徹底不須要 JavaScript 的參與。java

這就是本文要解決的問題。 Grid Shepherd 技術能夠爲咱們的數據提供所需的順序和結構,讓咱們更好地瞭解它的使用方式和應用場景。程序員

讓咱們來深刻研究一下。web

用 JavaScript 排序

咱們首先針對農場中一系列無序的動物進行排序。想象一下牛和羊在農場中清閒的樣子。咱們能夠用 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

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/…

更專業的使用 Shepherd

咱們還能夠經過 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 還能夠和任何非有序數據一塊兒使用:

  • 根據實時增加的投票數據對選民進行分組和統計;
  • 根據人們的地理位置、年齡、身高等進行分組;
  • 根據規則建立層次結構。

Shepherd 和可訪問性

grid-auto-flow:dense 不會改變網格的 DOM 結構 —— 它只是在視覺上對包含的元素從新排序。最後一個例子中會看到反作用:按字母順序排序時, counter 的數字被混淆了。更改 DOM 結構不只會影響使用屏幕閱讀器的用戶,還會影響對標籤遍歷的效果。

圓滿結束!

本文描述瞭如何將一個功能強大的 CSS 佈局工具(如grid)用於不符合傳統佈局需求的案例。咱們能夠看到 CSS Grid 的佈局優點和 JavaScript 的動態數據處理功能是重疊的,它能夠爲咱們提供更多的選擇和功能,是咱們可以爲所欲爲的去渲染數據。

歡迎關注前端公衆號:前端先鋒,獲取前端工程化實用工具包。

相關文章
相關標籤/搜索