在开始这个系列之前,我已经计划好了前两种语言。对于第三个问题,我决定询问 GitHub Copilot。它的建议是:
写更多关于 Python 的剧集
按字母顺序从 C 到 Rust,然后在本系列的其余部分继续介绍 Rust
实际上写了很多语言但有很多重复
HTML
好的,所以也许人工智能不会很快取代我们。但是最后一个建议并不太疯狂——HTML 可能不是一种编程语言,但 CSS 基本上变成了一种语言!
这一集不是关于居中元素或任何类似的事情,我们将用 CSS 编写真正的程序!
Hello World!
首先,Hello World!
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<style>
:root {
--who: "World";
}
body {
margin: 0;
min-height: 100vh;
font-size: 48px;
display: flex;
justify-content: center;
align-items: center;
}
body::after {
content: "Hello, " var(--who);
}
</style>
</head>
<body>
</body>
</html>
看起来和你预期的一样,HTML 正文中没有任何内容:
忽略body
上的规则,它们只是居中。有趣的技术在别处。
我们可以使用 –variablename: value; 在 CSS 中设置变量。 然后它被每个子元素继承。 我们可以将此类变量与 var(–variablename) 一起使用。
::after我们可以创建像和一样的“伪元素” ::before,并设置它们的内容。这些被添加到 CSS 中以处理诸如列表编号之类的事情。当你说
- One
- Two
,HTML实际上需要显示1. One 2. Two。那些“1”在哪里。和“2”。来自?仅来自这样的伪元素(在这种情况下::marker,但足够接近)。
大多数“使用 CSS 编程”将严重依赖伪元素。哦,它们的命名也很容易混淆 -body::after意思是“身体内部;毕竟内容”而不是“身体之后”。
FizzBuzz
现在让我们编写真正的程序,FizzBuzz!为此,我们将在 HTML 中放置 100 个空 span,并使用纯 CSS 执行 FizzBuzz:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<style>
body {
margin: 0;
min-height: 100vh;
counter-reset: fizzbuzz-counter;
}
span {
counter-increment: fizzbuzz-counter;
}
span::after {
content: ", ";
}
span:last-child::after {
content: ".";
}
span::before {
content: counter(fizzbuzz-counter);
}
span:nth-child(3n)::before {
content: "Fizz";
}
span:nth-child(5n)::before {
content: "Buzz";
}
span:nth-child(15n)::before {
content: "FizzBuzz";
}
</style>
</head>
<body>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
</body>
</html>
这是什么?一个格式很好的 FizzBuzz:
它是如何工作的?我们在这里使用了一些新技术。
每个跨度都有两个伪元素,::before和::after。
伪元素获取计数器值或“Fizz”或“Buzz”或“ ::beforeFizzBuzz”。为了支持表格上的浅色和深色条纹等重要功能,CSS 允许我们将规则应用于每 N 个元素的元素。稍后编写的具有相同特性的规则优先。所以span:nth-child(5n)::before只适用于每 5 个元素,除了那些span:nth-child(15n)::before优先的元素。
我们不为此使用 CSS 变量,我们使用 CSS 计数器。计数器用 来创建counter-reset: countername;,用 递增counter-increment: countername;,然后用 来访问counter(countername)。
伪元素要么是所有其他元素的::after逗号,要么是我们选择的最终元素的句点:last-child。这个功能实际上偶尔会在现实生活中使用,将列表表示为句子。
计数器也比你想象的更有用——列表不需要它们,但对于像节和小节编号的标题编号,CSS 可以很容易地用 counters 做到这一点。
斐波那契数列
现在我们遇到了一个非常意想不到的问题:
- CSS 有字符串和数字,没有办法将一个转换为另一个!
- 所有计算只能对数字进行
- 所有content显示必须是字符串
- counter(…)返回一个字符串
- counter只能设置为一个常数整数,或按一个常数整数递增,而不是计算出来的
完全莫名其妙。我一生中从未见过无法打印数字的语言,但这就是我们到达这里的方式。
好吧,让我们忽略所有这些,只制作一系列斐波那契数字大小的条形图。
我们需要使用 CSS 变量而不是 CSS 数字进行计算。CSS 变量可以访问它们的父变量,而不是它们的兄弟变量,所以我们需要做一些深度嵌套。同样不幸的是,虽然我们可以对它们进行一些计算,但 CSS 属性并没有真正排序,因此我们不能在一层上进行多个相互依赖的更改。因此,我们将为每个斐波那契数使用 3 个嵌套跨度。由于 CSS 没有任何 global :nth-element-globally(3n),我们将给它们特定的类。
有可能这些限制可以避免,我们很可能会获得 CSS 功能,让我们以更好的方式对其进行编码(很可能是数字到字符串的转换)。
即使有这些限制,我认为这仍然是一个很好的结果。
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<style>
:root {
--x: 0px;
--y: 1px;
}
body {
margin: 8px;
font-size: 48px;
min-height: 100vh;
}
span {
display: block;
}
span.a {
--z: calc(var(--x) + var(--y));
}
span.b {
--x: var(--y);
}
span.c {
--y: var(--z);
}
span.c::before {
display: block;
background-color: #480;
height: 5px;
width: var(--x);
margin: 2px;
content: "";
}
</style>
</head>
<body>
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
<span class="a"><span class="b"><span class="c">
</body>
</html>
看起来像这样:
肯定还有更多
虽然这是对 CSS 编程的快速介绍,但这绝不是它的限制。
人们一直在编写整个纯 CSS 游戏,比如这个或这个。
学习这会让你成为更好的前端开发人员吗?并不会,但这绝对很有趣