黄金比例,也称为黄金数、黄金比例或甚至神圣比例,是两个数之间的一种特殊关系,其值约为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 中的最终效果: