CSS 中的元素周期表

2025-06-07

CSS 中的元素周期表

就像太阳系一样元素周期表也用 CSS 制作过很多次……但从来没有像我将要向您展示的那样简单。

让我们从一些基本的语义标记开始:

<ol>
  <li data-mass="1.0078">
    <abbr title="Hydrogen">H</abbr>
  </li>
</ol>
Enter fullscreen mode Exit fullscreen mode

我们使用有序列表,,<ol>因为这是一个有序的元素系统。

然后我们<li>为每个元素设置一个标签,以及一个<abbr>标签。

该元素的名称<abbr>是“缩写”一词的缩写,很可爱。——
Heydon Pickering。

现在,我们无需在 Google 上搜索每个元素的原子质量,只需让 ChatGPT 填写其余标记即可。我们还要求它为每个元素添加一个由 3 个字母组成的类别,以指示该元素的类型,例如“惰性气体”(class="nbl")等。这样我们就得到了 118 个元素:

<ol>
  <li data-mass="1.0078" class="rnm">
    <abbr title="Hydrogen">H</abbr>
  </li>
  <li data-mass="4.0026" class="nbl">
    <abbr title="Helium">He</abbr>
  </li>
  <li data-mass="6.941" class="alk">
    <abbr title="Lithium">Li</abbr>
  </li> 
  <!-- etc. -->
</ol>
Enter fullscreen mode Exit fullscreen mode

它看起来还不太好;它只是一个带有元素缩写的编号列表。

1. H
2. He
3. Li
etc.
Enter fullscreen mode Exit fullscreen mode

我们将列表变成 18x10 的网格:

ol {
  all: unset;
  container-type: inline-size;
  counter-reset: element;
  display: grid; 
  font-size: 2cqi;
  gap: 1px;
  grid-template-columns: repeat(18, 1fr);
  grid-template-rows: repeat(10, 1fr);
}
Enter fullscreen mode Exit fullscreen mode

现在,我们将每个设置<li>为一个方框,并创建一个内部网格,将原子序数放在左上角,将质量(data-mass)放在右上角,将<abbr>标签放在下方:

li {
  aspect-ratio: 1 / 1;
  background: #EEEEEE;
  counter-increment: element;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  padding: .25ch;
  transition: scale .125s ease-in;
  &::before {
    content: counter(element);
  }
  &::after {
    content: attr(data-mass);
    grid-area: 1 / 2 / 2 / 2;
    justify-self: end;
  }
  &::before, &::after {
    font-size: .33em;
  }
}
Enter fullscreen mode Exit fullscreen mode

在查看最终效果之前,我们先让 ChatGPT 为它之前添加的“元素类型”类添加一些颜色。现在我们得到:

原始表

看起来不错,但跟我们在学校学的元素周期表不太一样。我们来加点网格魔法吧。

对于Helium,我们希望将其推到最后一列。由于我们知道网格宽度为 18 列,因此我们只需添加:

li {
  &:nth-of-type(2) { grid-column: 18; }
}
Enter fullscreen mode Exit fullscreen mode

由于这是一个有序列表,其nth-of-type值始终与每个元素的原子序数相对应。我们想将移至第 13 列:

li {
  &:nth-of-type(5), &:nth-of-type(13) { grid-column: 13; }
Enter fullscreen mode Exit fullscreen mode

让我们检查一下:

原始表 2

这确实是一种改进,但是由于grid-column只是将网格向前推,我们如何才能将元素 58-71 和 90-103(镧系元素和锕系元素)完全从其网格流中取出并将它们添加到主网格下方的两行中?

为此,我们可以使用grid-area,其中我们定义:

row-start / col-start / row-end / col-end

在我们的例子中,这将是:

li {
   /* Lanthenides */
  &:nth-of-type(58) { grid-area: 9 / 4 / 9/ 4; }
  &:nth-of-type(59) { grid-area: 9 / 5 / 9/ 5; }
  &:nth-of-type(60) { grid-area: 9 / 6 / 9/ 6; }
  /* etc. */

  /* Actinides */
  &:nth-of-type(90) { grid-area: 10 / 4 / 10 / 4; }
  &:nth-of-type(91) { grid-area: 10 / 5 / 10 / 5; }
  &:nth-of-type(92) { grid-area: 10 / 6 / 10 / 6; }
  / etc. */
}
Enter fullscreen mode Exit fullscreen mode

现在我们得到(为了清楚起见,我启用了Dev Tools 的网格可视化工具)

带网格预览的元素周期表

请注意,我们移出流程的元素之后的网格元素如何继续在主流程中!


过滤

现在,让我们使用这些之前由 ChatGPT 生成的“元素类型”类来过滤元素周期表。

首先,让我们添加一些基本的 HTML:

<fieldset>
  <legend>Filter</legend>
  <label>
    <input type="radio" id="alk" name="filter">
    Alkali Metals
  </label>
</fieldset>
Enter fullscreen mode Exit fullscreen mode

然后,我们要求 chatGPT 填写其余部分,并添加一个不带 的“全部”选项id

筛选

我们需要一堆 JavaScript 来过滤,对吧?不,我们可以用纯 CSS 来实现:

body:has(#alk:checked) li:not(.alk) { 
  opacity: 0.2;
}
Enter fullscreen mode Exit fullscreen mode

逻辑如下:如果body包含带有的复选框id="alk"并且被选中,则样式将应用于所有没有该类的<li>元素.alk

对所有类型和类别重复此操作。

让我们点击“准金属”:

准金属

那有多酷?


本教程到此结束……但是等等……那个 Heisenberg 滤镜是干什么用的?它不在 ChatGPT 的滤镜列表中吗?

让我们点击它:

海森堡

...现在你知道我最喜欢的电视节目了!

演示

这是一个 Codepen — 尽管它具有完全响应能力,但我建议在更大的屏幕上查看它:

文章来源:https://dev.to/madsstoumann/the-periodic-table-in-css-3lmm
PREV
12 个让你惊喜的开源项目🔥🧑‍💻
NEXT
前端机构