大家读中学的时候一定都见过元素周期表吧?有没有心痒难耐,想自己动手试试制作一个?
什么?你说太难了,你做不来??!
那你一定要看看我是如何用前端技术一步步制作化学元素周期表的,简单又快捷,再一次赞美 CSS 和 ChatGPT!
先来看看最后的效果图:
接下来,让我们从基本的语义标记启动我们的元素周期表制作吧:
<ol>
<li data-mass="1.0078">
<abbr title="Hydrogen">H</abbr>
</li>
</ol>
因为这是一个有序的元素系统,所以使用有序列表<ol>
。
然后,给每个元素提供一个<li>
tag 和一个<abbr>
tag。
敲黑板,注意了,可别再傻乎乎地去网上一个个地搜索每个元素的原子质量,ChatGPT 能帮我们填写剩余的标记。
除此之外,好帮手 ChatGPT 还帮我们给每个元素添加了一个 3 个字母的类,指示元素的类型,例如,noble gas 惰性气体(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>
tag放在下方:
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 给它上点色,在element-type
类添加颜色。这样我们的元素表看起来就漂亮多了:
但跟我们在学校里学的元素周期表有点不一样,怎么办?不用担心,grid-magic
来帮忙。
首先是 He(氦)元素,我们希望把它挪到最后一列。因为网格有 18 列,所以我们只需:
li {
&:nth-of-type(2) { grid-column: 18; }
}
由于这是有序列表,因此nth-of-type
值将始终对应于每个元素的原子序数。
接着我们将 B(硼)和 Al(铝)移动到第 13 列:
li {
&:nth-of-type(5), &:nth-of-type(13) { grid-column: 13; }
就是这样,看起来有点像了:
但是grid-column
只能向前推网格,而 58-71 号元素(镧系元素)和 90-103 号元素(锕系元素)需要在主网格下方另起 2 行,该怎么办呢?
我们有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 的grid-visualizer
):
过滤
这一步中,我们将使用之前 ChatGPT 生成的element type
类来过滤元素周期表。
首先,依然是添加基本的 HTML:
<fieldset>
<legend>Filter</legend>
<label>
<input type="radio" id="alk" name="filter">
Alkali Metals
</label>
</fieldset>
还是老样子,让 ChatGPT 继续写完剩余代码。添加没有id
的All
选项:
不需要搞一大堆 JavaScript 代码来过滤,纯 CSS 就可以办到:
body:has(#alk:checked) li:not(.alk) {
opacity: 0.2;
}
逻辑是这样的:如果body
包含具有id=“alk”
的复选框,且被选中,那么样式将应用于所有没有.alk
类的<li>
元素。
对所有类型和类重复上述步骤。
例如我们点击metalloids
(半金属),看到了吗:
是不是超酷的?
本教程到此结束……等等……那个Heisenberg
干什么用的?有点莫名其妙啊!
源码
最后是所有的代码和演示。拿走不谢!!
“在我的公众号后台回复数字“5080”获取源码下载链接。
END
热门推荐