Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

使用自定义属性打乱 CSS 网格

Posted on 2025-11-24

记录网格重组过程

在今年柏林举行的Beyond Tellerrand大会上,Andy Bell 发表了题为“把核心代码做好,弹性代码自然会随之而来”的精彩演讲,展示了如何在团队内部理性地讨论编码问题。他还在自己的博客上发表了一篇更深入的文章。

Andy 描述的问题是,他有一个CSS网格系统,其中的内容列并排排列,然后客户要求每次页面刷新时随机排列网格的顺序,以便公司的每个部门都能获得短暂的展示机会。Andy 非常重视代码的弹性,因此他对使用 JavaScript 解决此类问题持批评态度。移动整个DOM结构会很慢,而且每次交互时都将整个网格作为组件重新写入也存在风险。

于是我琢磨着该怎么办,然后想起了CSS的order属性可以用于flex和grid布局项。利用这个属性,你可以重新排列元素的视觉顺序。


你可能从未听说过的优秀乐队

伊里叛乱
路灯宣言
Dubioza Kolektiv
爱尔兰芥末酱

如果将第三个元素的顺序改为减一,它就会排在第一位:


ul {
显示方式:flex;
弯曲方向:柱;
间隙:1em;
}

#dk {
顺序:-1;
}

CSS 排序示例

这样就把所有重新排序的工作都保留在了CSS引擎中。但是由于CSS目前还无法实现随机排序,我们需要一些 JavaScript 代码来实现这个功能。最初的想法是将排序作为内联样式添加,但这仍然需要操作DOM ,并且需要遍历所有元素。因此,我考虑使用CSS自定义属性:


ul {—customorder: -1;
显示方式:flex;
弯曲方向:柱;
}

#dk {
订单:var(—customorder);
}

这样我就可以访问父元素上的 `customorder` 属性了:


let ul = document.querySelector('ul');
ul.style.setProperty('—customorder',-1);

综合以上所有功能,我为您带来GridShuffle ,您可以在 GitHub 上查看代码:


关于

这是 order.html 文件。

消息

最新消息将显示在此处。

接触

联系信息将显示在此处。

案例研究

案例研究将在此展示。

洗牌

上面的网格会在每次页面刷新或点击“随机排列”按钮时重新排列。实现这种效果的方法有很多,但本示例仅使用CSS属性来设置网格项的顺序。除了访问父元素的CSS属性之外,没有修改HTML 代码,也没有进行任何DOM操作。这应该能带来很高的性能。JavaScript 代码通过更改定义网格项顺序的CSS变量来轮换网格项的顺序。以下是用于设置网格和随机排列网格项的相关代码:

  
	

#contentgrid {—items: 4;—item1-order: 1;—item2-order: 1;—item3-order: 1;—item4-order: 1;
显示方式:网格;
间隙:20px;
grid-template-columns: repeat(
自动适应,最小最大尺寸(200像素,1fr)
);
}

#about { order: var(—item1-order); }

#news { order: var(—item2-order); }

#联系{ 订单: var(—item3-订单); }

#casestudies { order: var(—item4-order); }

我们将每个元素的顺序定义为 `1`,这意味着如果我们将其中任何一个元素的值设置为 `0`,它将在网格中首先显示。例如,如果我们执行以下操作,“案例研究”部分将显示在最前面:

  
	

#contentgrid {—items: 4;—item1-order: 1;—item2-order: 1;—item3-order: 1;—item4-order: 0;
/* … */
}

#about { order: var(—item1-order); }

#news { order: var(—item2-order); }

#联系{ 订单: var(—item3-订单); }

#casestudies { order: var(—item4-order); }

这可以在服务器端或使用 JavaScript 实现,如下所示:


let root = document.querySelector('#contentgrid');
let itemcount = getComputedStyle(root)。
getPropertyValue('—items');
let old = 1;
const shuffleorder = () => {
let random = Math.floor(Math.random() * itemcount) + 1;
root.style.setProperty('—item' + old + '-order', 1);
root.style.setProperty('—item' + random + '-order', 0);
旧 = 随机;
};
shuffleorder();

我们通过读取根元素上 `–items` CSS属性的值来获取网格中的项目数量,并将当前第一个项目存储在 `old` 变量中。然后,我们随机选择一个介于 1 和项目总数之间的数字,并将旧项目的顺序设置为 `1`,将随机生成的新项目设置为 `0`。最后,我们将 `old` 重新定义为新项目的顺序。

这是最基本的方法,但它并非真正的打乱,因为它只是按固定顺序旋转元素。您可以参考“打乱网格”示例,了解更高级的实现方式,该示例会随机化所有元素的数组。您还可以通过移动数组来旋转元素,如“旋转网格”示例所示。

其他示例也不需要设置任何自定义属性,而是直接创建它们。这意味着需要进行更多一些的JS和 DOM 交互,但简化了流程。


let root = document.querySelector('#contentgrid');
let cssvar = `—item$x-order`;
// 获取物品数量
let elms = root.querySelectorAll(
root.firstElementChild.tagName
);
all = elms.length;
// 初始化顺序数组和
// 设置商品顺序
let orders = [];
for (let i = 1; i <= all; i++) {
orders.push(i);
elms[i – 1].style.setProperty(
'order', 'var(' + cssvar.replace('$x', i) + ')'
);
root.style.setProperty(cssvar.replace('$x', i), i);
}

但如果你完全不想使用 JavaScript 来实现这个目标呢?Andy 在演讲中展示的解决方案是在服务器端随机化页面顺序,这在很多语言中都很容易实现。他使用 Jekyll 的方案是每隔几分钟生成一次页面,并使用 sample 过滤器,这看起来有点浪费资源,但很稳定。

当前和未来的纯CSS解决方案

目前仅使用CSS无法实现随机化或打乱元素顺序。不过,有一些方法可以利用 Sass ,但这需要进行预处理。另一种巧妙的方案是使用 `@property`,而 `@property` 目前尚未得到广泛支持。

CSS规范定义了一个random() 函数,可以在不使用 JavaScript 的情况下实现这种效果。但是,目前只有Safari 技术预览版 170支持此功能。

CSS 的polyfill 并不容易,所以目前来说,在你的解决方案中添加少量 JavaScript 来实现类似的效果或许是个不错的选择。在我看来,这种方法是一个不错的折衷方案,因为它保留了CSS的功能,而无需重新调整整个DOM树或重写整个网格系统。

原文: https://christianheilmann.com/2025/11/24/shuffling-a-css-grid-using-custom-properties/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Anil Dash
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Big Technology
  • Bits about Money
  • Brandon Skerritt
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • eighty twenty
  • Elad Gil
  • Ellie Huxtable
  • Ethan Dalool
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • HeardThat Blog
  • Henrique Dias
  • Herman Martinus
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Li Haoyi
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Maggie Appleton
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mind Matters
  • Mostly metrics
  • Naval Ravikant
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • PostHog
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Rohit Patel
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Steph Ango
  • Stephen Wolfram
  • Steve Blank
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • Wes Kao
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme