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

翻譯:瘋狂的技術宅

原文:https://css-tricks.com/using-...javascript

未經許可,禁止轉載!css

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

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

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

讓咱們來深刻研究一下。程序員

用 JavaScript 排序

咱們首先針對農場中一系列無序的動物進行排序。想象一下牛和羊在農場中清閒的樣子。咱們能夠用 Array.prototype.sort 方法以編程方式對其排序分組並展現在頁面上:web

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上的演示:https://codepen.io/Achilles_2...segmentfault

爲了放養這些動物,咱們必須將它們圍在一個公共區域內,這就是咱們 <main> 元素要作的事。經過使用 display:grid 設置該柵欄,咱們建立了一個網格格式化上下文,能夠在其中定義每種動物應該佔據的列(或行)。

.sheep { grid-column: 1; }
.cow { grid-column: 2; }

clipboard.png

經過 grid-auto-flow:dense,每隻動物都會讓本身進入對應定義區域的第一個可用點。也能夠用於任意數量的不一樣排序規則—— 只需再定義另外一個列,數據就會被神奇地引導到其中。

main
  display: grid;
  grid-auto-flow: dense;
}

.sheep { grid-column: 1; }
.cow { grid-column: 2; }

CodePen:https://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演示:https://codepen.io/Achilles_2...

Grid Shepherd 還能夠和任何非有序數據一塊兒使用:

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

Shepherd 和可訪問性

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

圓滿結束!

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


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章


歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索