黄金比例,也称为黄金数、黄金比例或甚至神圣比例,是两个数之间的一种特殊关系,其值约为1.618。它通常用希腊字母“phi”来表示。令人着迷的是,这个比例与斐波那契数列有着密切的联系——一个数列,其中每个数都是前两个数的和。斐波那契数列从0、1开始,然后继续:1、2、3、5、8、13、21等。随着数列的延续,每个数与其前一个数的比例越来越接近1.618,即phi。这种独特的比例在自然界、艺术和建筑中随处可见,使其既具有数学上的吸引力,又具有视觉上的美感!
在本教程中,我们将使用一些网格声明和一些额外的技巧,用CSS重新创建黄金比例图。
让我们开始吧!
我们将使用斐波那契数列的这一部分:
1, 1, 2, 3, 5, 8, 13, 21
进入全屏模式 退出全屏模式
那就有8位数字,所以我们的标记将由一个包含8个 <li>
元素的 <ol>
组成。
在 CSS 网格中,我们将创建一个画布,宽度为最后两个数字之和,13 + 21 = 34
,高度为最大的数字,21
:
ol {
all: unset;
display: grid;
grid-template-columns: repeat(34, 1fr);
grid-template-rows: repeat(21, 1fr);
list-style: none;
}
进入全屏模式 退出全屏模式
目前还没有太多可看的内容,但如果我们启用 Dev Tool 的 Grid Inspector,我们就可以看到网格了:
接下来,我们将为 <li>
元素添加一些常见的样式:
li {
aspect-ratio: 1 / 1;
background: var(--bg);
grid-area: var(--ga);
}
进入全屏模式 退出全屏模式
仍然没有内容可看,所以让我们用一些内容填充 --bg
(background-color
)和 --ga
(grid-area
)变量:
&:nth-of-type(1) {
--bg: #e47a2c;
--ga: 1 / 1 / 22 / 22;
}
&:nth-of-type(2) {
--bg: #baccc0 ;
--ga: 1 / 22 / 23 / 35;
}
&:nth-of-type(3) {
--bg: #6c958f;
--ga: 14 / 27 / 22 / 35;
}
&:nth-of-type(4) {
--bg: #40363f;
--ga: 17 / 22 / 22 / 27;
}
&:nth-of-type(5) {
--bg: #d7a26c;
--ga: 14 / 22 / 17 / 25;
}
&:nth-of-type(6) {
--bg: #ae4935;
--ga: 14 / 25 / 17 / 27;
}
&:nth-of-type(7) {
--bg: #e47a2c;
--ga: 16 / 26 / 17 / 27;
}
&:nth-of-type(8) {
--bg: #f7e6d4;
--ga: 16 / 25 / 17 / 26;
}
进入全屏模式 退出全屏模式
现在,我们得到了这个:
酷!那么发生了什么?我们为每个 <li>
元素设置了它自己的 background-color
,使用了 --bg
自定义属性。然后我们使用 grid-area
来放置和调整网格中的矩形。grid-area
是一个简写,代表:
row-start / col-start / row-end / col-end
进入全屏模式 退出全屏模式
现在,让我们来创建螺旋效果。虽然CSS不能直接绘制螺旋,但我们可以通过在每个<li>
上添加圆形的::after
伪元素来模拟螺旋效果。
li {
/* 保持之前的内容 */
overflow: hidden;
position: relative;
&::after {
aspect-ratio: 1 / 1;
background-color: rgba(255, 255, 255, .3);
border-radius: 50%;
content: '';
display: block;
inset: 0;
position: absolute;
}
}
进入全屏模式 退出全屏模式
这给我们带来了:
还差点意思,但是如果我们将圆的大小加倍并将其稍微移动,看起来就会好一些:
&::after {
/* 如上 */
scale: 2;
translate: var(--tl);
}
进入全屏模式 退出全屏模式
然而,直到我们为每个 <li>
更新 --tl
(translate)属性时,变化才变得明显:
&:nth-of-type(1) {
--tl: 50% 50%;
}
&:nth-of-type(2) {
--tl: -50% 50%;
}
/* 以此类推,其余部分也是如此 */
进入全屏模式 退出全屏模式
现在我们得到了这个:
发生了什么?
我们创建了一个比元素大两倍的圆,然后使用 translate 将圆向不同方向移动,以呈现出连续的螺旋效果。通过调整每个元素的位移,这些圆“流动”在一起,模仿了螺旋的形态。
最后,因为我们给 <li>
元素添加了 overflow: hidden
,当圆超出容器时会被“裁剪”,从而给我们一种完美的螺旋效果的错觉!
这里是 CodePen 中的最终效果: