CSS 中的元素周期表
就像太阳系一样,元素周期表也用 CSS 制作过很多次……但从来没有像我将要向您展示的那样简单。
让我们从一些基本的语义标记开始:
<ol>
<li data-mass="1.0078">
<abbr title="Hydrogen">H</abbr>
</li>
</ol>
我们使用有序列表,,<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>
它看起来还不太好;它只是一个带有元素缩写的编号列表。
1. H
2. He
3. Li
etc.
我们将列表变成 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);
}
现在,我们将每个设置<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;
}
}
在查看最终效果之前,我们先让 ChatGPT 为它之前添加的“元素类型”类添加一些颜色。现在我们得到:
看起来不错,但跟我们在学校学的元素周期表不太一样。我们来加点网格魔法吧。
对于Helium,我们希望将其推到最后一列。由于我们知道网格宽度为 18 列,因此我们只需添加:
li {
&:nth-of-type(2) { grid-column: 18; }
}
由于这是一个有序列表,其nth-of-type
值始终与每个元素的原子序数相对应。我们想将硼和铝移至第 13 列:
li {
&:nth-of-type(5), &:nth-of-type(13) { grid-column: 13; }
让我们检查一下:
这确实是一种改进,但是由于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. */
}
现在我们得到(为了清楚起见,我启用了Dev Tools 的网格可视化工具):
请注意,我们移出流程的元素之后的网格元素如何继续在主流程中!
过滤
现在,让我们使用这些之前由 ChatGPT 生成的“元素类型”类来过滤元素周期表。
首先,让我们添加一些基本的 HTML:
<fieldset>
<legend>Filter</legend>
<label>
<input type="radio" id="alk" name="filter">
Alkali Metals
</label>
</fieldset>
然后,我们要求 chatGPT 填写其余部分,并添加一个不带 的“全部”选项id
:
我们需要一堆 JavaScript 来过滤,对吧?不,我们可以用纯 CSS 来实现:
body:has(#alk:checked) li:not(.alk) {
opacity: 0.2;
}
逻辑如下:如果body
包含带有的复选框id="alk"
并且被选中,则样式将应用于所有没有该类的<li>
元素。.alk
对所有类型和类别重复此操作。
让我们点击“准金属”:
那有多酷?
本教程到此结束……但是等等……那个 Heisenberg 滤镜是干什么用的?它不在 ChatGPT 的滤镜列表中吗?
让我们点击它:
...现在你知道我最喜欢的电视节目了!
演示
这是一个 Codepen — 尽管它具有完全响应能力,但我建议在更大的屏幕上查看它:
文章来源:https://dev.to/madsstoumann/the-periodic-table-in-css-3lmm