文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

CSS 如何改变网格布局偶数行的排序?

2024-11-30 10:16

关注

图片

布局本身没什么奇怪的,就是 「4 * 2」 的网格,比较特殊的是第二行布局是从右往左的,整体是一个这样的顺序

图片

而这个列表是通过一个数组动态渲染的,可能有很多同学会将这个数组分成两份,然后将第二份进行反向,类似于这样

let arr1 = list.slice(0, 4)
let arr2 = list.slice(4, 8).reverse()

然后,由于第二行的第一个其实是原数组的第八个,还需要针对第二行做额外的处理,比如序列

// 第一行
第 {{ i }} 个
// 第二行
第 {{ 8 - i }} 个

而且,如果有点击事件,传值也需要额外处理,虽然也能实现,但显然是太麻烦,而且还容易出 bug。

那么,有没有其他更简单、更稳定的方式来解决呢?也就是如何让第二行子项反向呢?

一、flex 布局实现

由于这里是动态渲染,所以最理想的结构应该是这样的,直接一层循环搞定

1
2
3
4
5
6
7
8

通过 flex 或者 grid都很容易实现4 * 2的布局,先用 flex实现

.list{
  display: flex;
  width: 600px;
  gap: 20px;
  flex-wrap: wrap;
}
.item{
  width: calc( (100% - 60px) / 4 );
  aspect-ratio: 1/1;
  background: royalblue;
  color: #fff;
  font-size: 30px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}

可以得到这样的布局

图片

有什么办法在不改变 html 的情况下改变第二行的位置呢?🤔

在 flex中,可以直接通过order进行排序,order越大,元素越靠后。

https://developer.mozilla.org/zh-CN/docs/Web/CSS/order

比如,我们将第 5 个元素的order设置成1

.item:nth-child(5){
  order: 1
}

由于默认是0,现在第 5 个元素的order最大,所以它跑到了最后面

图片

按照这样的规则,我们可以将第 5、6、7、8 个子项的order分别一次减少就行了(大于0)

.item:nth-child(5){
  order: 4;
}
.item:nth-child(6){
  order: 3;
}
.item:nth-child(7){
  order: 2;
}
.item:nth-child(8){
  order: 1;
}

这样第二行就反向了,如下

图片

当然还可以在循环的时候,加上 CSS 变量

1
2
3
4
5
6
7
8

然后可以用 「calc」动态去改变order,如下

.item:nth-child(n + 5){
  order: calc( 8 - var(--i))
}

同样能达到相同的效果,完整代码可以查看

二、grid 布局实现

还是同样的布局,现在换 grid 实现,正常情况下,可能会直接用repeat(4, 1fr)来实现一个 4 * 2的布局

.list{
  display: grid;
  width: 600px;
  gap: 20px;
  grid-template-columns: repeat(4, 1fr);
}
.item{
  aspect-ratio: 1/1;
  background: royalblue;
  color: #fff;
  font-size: 30px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}

效果如下

图片

那么,如何让下面一行反过来呢?

除了使用上面的方式,还可以用带有名称的grid-template-areas来实现,比如我们这样命名

.list{
  
  grid-template-areas: 
    'a1 a2 a3 a4'
    'a5 a6 a7 a8';
}

这样就划分成了a1~a8一共八块区域,为了方便映射,我们可以在生成 html时,通过 CSS 变量带上这些名称

1
2
3
4
5
6
7
8

这样就可以很方便的把每一个子项“填入”对应的区域了

.item{
  
  grid-area: var(--i);
}

现在仍然是默认顺序,如果要改变第二行的顺序,直接grid-template-areas就行了

.list{
  
  grid-template-areas: 
    'a1 a2 a3 a4'
    'a8 a7 a6 a5'; 
}

这样就很方便直观的改变了子项的位置了,效果如下

图片

完整代码可以查看

三、更加自由的“蛇形布局”

上面的例子只有两行,如果有多行呢,并且行数不定,如何处理呢?就像这样的

图片

这种时候用 grid 可能少许不方便了(可能我还没找到精髓😂),下面用 flex 实现

目前 CSS 中并没有能够检测第几行的选择器,所以只能用其他方式。假设每一行的个数是确定的,这里是 4,那么,第二行就是5、6、7、8,隔一行,第四行就是13、14、15、16,依次类推。

有什么方式可以匹配第几个呢?没错,就是:nth-child,由于是隔一行,所以是每 8 个一个循环,可以这样来选择偶数行,如下

.item:nth-child(8n + 5){
  
}
.item:nth-child(8n + 6){
  
}
.item:nth-child(8n + 7){
  
}
.item:nth-child(8n + 8){
  
}

由于默认的order是0,如果改变其他的order肯定会跑到后面去,为了避免影响,可以先手动设置order

.item{
  
  order: var(--i);
}

下面要对偶数行的顺序进行调整,比如第二行

图片

第 1 个的位置调到第4个位置,所以 order需要加 3

第 2 个的位置调到第3个位置,所以 order需要加 1

第 3 个的位置调到第2个位置,所以 order需要减 1

第 4 个的位置调到第1个位置,所以 order需要减 3

最后实现就是

.item:nth-child(8n + 5){
  order: calc(var(--i) + 3)
}
.item:nth-child(8n + 6){
  order: calc(var(--i) + 1)
}
.item:nth-child(8n + 7){
  order: calc(var(--i) - 1)
}
.item:nth-child(8n + 8){
  order: calc(var(--i) - 3)
}

这样就实现了行数不固定的“蛇形布局”,完整代码如下

四、优势和总结

这样实现有什么优势呢?很明显 JavaScript 无需关注布局,只用处理业务逻辑就行,也无需单独对第二行元素做特殊处理,特别是序列,之前很容易混乱,最重要的是实现更加清晰明了,也更加稳定。下面总结一下要点

  1. 用 js 来修改布局比较麻烦,而且逻辑容易混乱
  2. flex 中可以用 order 来改变子项位置
  3. 借助 CSS 变量可以更加方便地映射到每个子项
  4. grid 中可以用 grid-template-areas 手动指定每个子项的位置
  5. 蛇形布局可以用 nth-child 选中偶数项,从而改变位置

按照我的经验,布局最好 CSS 单独完成,不要让 JS 参与其中,这样逻辑也会更加清晰。

来源:前端侦探内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯