用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 的动态数据处理功能是重叠的,它能够为咱们提供更多的选择和功能,是咱们可以为所欲为的去渲染数据。

欢迎关注前端公众号:前端先锋,获取前端工程化实用工具包。

相关文章
相关标签/搜索