我如何仅使用 CSS 渐变来重建宝丽来相机
最初发表于fossheim.io
之前我用 CSS 重新设计了一个旧计算器。制作过程中我非常开心,所以这次我决定用宝丽来相机来做同样的设计。
在本教程中,我将指导您完成我的过程,并解释如何自己在 CSS 中复制实体产品。
由于这是一个相当大的项目,我不会单独介绍每个组件,但完整的代码可以在CodePen、GitHub和Glitch上找到。
我强烈建议对其进行分叉并进行尝试,以进一步了解每个组件是如何构建的。
您需要:
- 像 Figma 这样的程序可以从图像中选择颜色
- HTML/CSS 基础知识
- 理解 CSS 渐变
我还建议准备一些纸笔,以便勾勒出项目的结构。在创建 HTML 和 CSS 时,我不断地在纸上分解各个组件。
步骤 0:准备
首先,你需要找到一张待重建物体的高质量图像。你需要大量挑选颜色和测量尺寸,所以图像质量好非常重要。
这是我一开始用的那张。正如你所见,我还找了一张已经从相同角度、相同光线下拍摄的照片,与我想要的效果一致。
步骤 1:确定结构
一旦我决定要处理哪个图像,我就会对其进行分析并勾勒出基本结构,然后将其转换为 html。
执行此操作时请记住以下几点:
- 物理组件。如果是相机上的物理按钮或组件(例如镜头或闪光灯),您也希望将其作为代码中的单独组件。这样可以更轻松地设置样式,并方便您将来添加一些额外功能。例如,您可以让闪光灯在按下快门时亮起。
- 颜色和尺寸。相机底部(打印机所在位置)为黑色,且比顶部略宽。虽然严格来说,它们可能是同一物理组件(相机机身)的一部分,但将其拆分为顶部和底部组件可以带来更大的灵活性,并使设置颜色和尺寸变得更加容易。
- 阴影、高光和反光。有些组件如果拆分成几个子组件会更容易重现。例如,镜头在玻璃上有一些反光,但在材质的其他部分是看不到的。所以我把这个部分拆分成了突出相机的实体部分和顶部的玻璃。
考虑到这一点,结构就变成了这样:
- 相机
- 顶部
- 镜片
- 取景器
- 闪光
- 快门
- 计时器
- ...
- 底部
- 打印机
- 标识
- 切换
- ...
- 顶部
第 2 步:将结构翻译成 HTML
一旦您将图像分成不同的部分并在纸上布置好结构,您就可以很容易地将其转换为 HTML。
<div class="camera">
<div class="top">
<div class="flash"></div>
<div class="timer"></div>
<div class="sensor"></div>
<div class="lens"><div class="glass"></div></div>
...
</div>
<div class="bottom">...</div>
</div>
现在我们已经准备好了,我们可以开始 CSS 工作并实际创建一些视觉效果。
步骤 3:逐个设置每个组件的样式
从轮廓开始
我建议从较大、较容易的部件开始。比如宝丽来相机,最好从机身顶部或底部开始。这些部件细节最少,也决定了相机的整体结构,所以它们有助于你稍后定位其他部件。
把大件部件安装好后,就可以开始安装其他部件了。之后的安装顺序并不重要。我是从下往上安装的,但具体顺序取决于你。
如果您对 CSS 中的渐变还不熟悉,您可能需要先了解一些细节较少的项目(例如红色快门或白色定时器按钮),然后再了解更复杂的项目,例如镜头或闪光灯。
确定尺寸、位置和颜色
您需要在程序中打开图片(我使用了 Figma),您可以在其中选择颜色并测量每个组件的大小。
底部的彩虹就是一个很好的例子。我首先在它上面画了一个矩形来测量宽度和高度,然后在CSS中设置。同样的方法也可以用于确定位置:
.rainbow {
display: block;
width: 40px;
height: 46px;
position: absolute;
top: 100px;
left: 80px;
}
最好对所有组件进行绝对定位,除了外部相机机身(可以)position: relative
。通过绝对定位,一个组件的宽度和高度不会影响其他组件的定位或大小。
至于颜色,我画了几个形状,并使用颜色选择器为每个部分获取正确的颜色代码。对于大多数物理组件,我使用了渐变色而不是纯色,即使组件看起来或多或少有些扁平。
例如,相机机身顶部有三种不同的白色作为底色。虽然不太显眼,但这样做确实让设计更具立体感。
我通常会从组件顶部选取一种颜色,从底部选取另一种颜色,然后以此为基础创建线性渐变。尽量不要选取阴影后面的颜色,因为它们很容易变得太暗。我们稍后会为每个组件添加阴影。
如果您对外观不满意,可能需要添加第三种或第四种颜色,或者稍微降低颜色之间的对比度。这是一个反复试验的过程,因此您需要同时打开输出和代码。
分层渐变
在这样的项目中,你需要在同一个 div 中叠加渐变。我的意思是,叠加很多渐变。
堆叠渐变时需要记住的一件重要事情是它们的显示顺序。让我们来看以下示例:
background-image: linear-gradient(green,blue),
linear-gradient(red,orange),
linear-gradient(black,white);
绿色渐变显示在顶部,红色渐变显示在下方,黑色渐变显示在底部。我们也可以用类似的方式决定渐变的大小、位置和重复次数:
background-size: 10px 20px, /* green/blue gradient */
40px 5px, /* red/orange gradient */
30px 35px; /* black/white gradient */
background-position: top left, center, bottom right;
background-repeat: no-repeat, no-repeat, repeat;
示例 1:上身
对于身体的顶部,我主要想要两个堆叠的渐变:
- 水平渐变,有四种略有不同的白色色调(从身体的顶部、中部和底部选取)
- 顶部有一个垂直渐变,从两侧略微透明的白色到中间完全透明的白色
linear-gradient(
90deg,
rgba(243,243,243,0.75),
rgba(243,243,243,0) 15% 85%,
rgba(243,243,243,0.75)
),
linear-gradient(#DDD9DA, #E2DEDF, #EAE8EB, #F3F1F4);
示例 2:闪光灯
现在我们来看看一个更复杂的组件,闪光灯。
这个有很多渐变:背景渐变(白色,浅灰色,黑色,深灰色,浅灰色,白色),水平线(透明,浅灰色,白色,透明),然后是垂直线,然后是顶部和底部的白色方块。
选择渐变颜色后,我们可以将其转换为 CSS,如下所示:
background-image: linear-gradient(#EDECEA,#F6F6F8) /*Top white square*/,
linear-gradient(
90deg,
rgba(247,246,244,0) 3%,
rgba(247,246,244,0.5) 3% 6%,
..., /*Repeat*/
rgba(247,246,244,0) 95%,
rgba(247,246,244,0.5) 95% 98%,
), /*Thin Vertical lines*/
linear-gradient(
90deg,
rgba(186,184,185,0.1),
rgba(247,246,244,0.65),
rgba(186,184,185,0.1)
), /*Bold vertical line 1*/
linear-gradient(
90deg,
rgba(186,184,185,0.1),
rgba(247,246,244,0.65),
rgba(186,184,185,0.1)
), /*Bold vertical line 2*/
linear-gradient(
#E3DEDA 15%,
#AFAAA6 25% 35%,
transparent 45%
), /*Horizontal lines*/
linear-gradient(
#F0EFED 10%,
#B0ABA7 20%,
#403C3B 40%,
#2F2B2A 43%,
#292524 45% 55%,
#696562 65% 75%,
#C2BFBA 82% 86%,
#DEDAD7 90% 93%,
#C9C6C1 94% 96%,
#FFFEFA 98%
); /*White/gray/black background*/
如果我们只是渲染它,我们只会看到顶部有一个大的白色渐变(linear-gradient(#EDECEA,#F6F6F8)
),因为默认情况下每个渐变都设置为 100% 宽度和高度并堆叠在一起。
因此,让我们测量顶部渐变的大小,以及垂直线应该出现的位置。
background-size: 42px 20px, /*White reflection*/
42px 100%, /*Thin vertical lines*/
3px 100%, /*Bold vertical line*/
3px 100%, /*Bold vertical line*/
100% 3px, /*Horizontal lines*/
100%; /*Background*/
background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, repeat, repeat, no-repeat;
background-position: 24px top, 25px top, 22px top, 64px top, center, center, center;
添加反射和阴影后(将在下一节中解释),我们的闪光灯最终看起来像这样:
边框、阴影和高光
在使用渐变样式设置组件后,显然还缺少一些东西:深度、阴影和高光。就像堆叠渐变一样,我们也可以将阴影堆叠在一起。
它的工作原理与渐变完全相同,首先提到的是位于顶层的渐变。
在这个例子中,我们最终在蓝色阴影上出现了红色阴影:
box-shadow: 1px 1px 1px 1px red, 2px 2px 2px 2px blue;
如果我们颠倒顺序,蓝色阴影就会位于顶部,遮住红色阴影:
box-shadow: 2px 2px 2px 2px blue, 1px 1px 1px 1px red;
示例:白色计时器按钮
最简单的例子就是白色计时器按钮,它能很好地展现阴影的效果。放大图片后,我们可以看到创建深度所需的两样东西:
- 整个按钮周围有一个非常薄的黑色阴影,底部略厚
- 按钮内部顶部的细白色高光
让我们从阴影开始:
box-shadow: 0px /*No left or right offset*/
0.5px /*Moved 0.5px downwards*/
1px /*Blur of 1px*/
0.5px /*Sized up with 0.5px*/
#605C5B /*Black color*/;
接下来,我们可以添加高亮。我们希望高亮显示在按钮内部,而不是外部,因此我们将使用该inset
值。
box-shadow: 0px 0.5px 1px 0.5px #605C5B, /*shadow*/
1px 1px 1px #FFFBFC inset; /*highlight*/
/*1px moved down, 1px to the right, 1px blur, white color, inside the div*/
示例:闪光灯周围的深度
让我们回到更复杂的例子——闪光灯。我们希望组件稍微凸起一些,为此我们需要一个白色阴影,并在其下方添加一个灰色阴影。
之后,我们还想在里面添加一些阴影:
- 白线网格周围的灰色边框
- 突出显示在顶部
- 突出显示底部
- 顶部有阴影
box-shadow: -1px -1px 1px #BDB8B5,
-1.5px -2.1px 0.5px #24201D,
-4px 4px 3px 3px #F4F0EF,
-5px 8px 8px #ABA6AA,
0.25px 1px 1px 5px #3E3A38 inset,
0 -6px 1px 1px #F6F6F8 inset;
反思
一些组件也需要更多反射,例如镜头内部的玻璃和取景器内部的玻璃。在这种情况下,值得为玻璃创建一个额外的 div。让我们看看我是如何解决这个问题的。
示例:镜头玻璃上的反射
如果我们看中间,我们会看到我在这里使用了 4 个渐变:
- 填满整个背景的径向渐变,从近黑色逐渐变为深紫色。这是玻璃的颜色。
- 顶部的浅绿色反射。这是一个径向渐变,中间是绿色,两侧是透明色,向外延伸并向上移动,因此只有角落可见。
- 底部深绿色的反射,其作用与顶部反射相同,只是颜色不同。
- 中间的光反射,这是另一个径向渐变,这次从浅黄色变为透明黄色。
background-image: radial-gradient(rgba(236, 234, 237, 0.3) 50%, transparent 60%),
radial-gradient(rgba(193, 189, 186, 0.3) 50%, transparent 60%),
radial-gradient(#5B5758 45%, #302C2D, #131112);
background-size: 106% 32%, 106% 25%, 100%;
background-repeat: no-repeat;
background-position: -3px -7px, bottom -8px left -3px, center;
概括
- 选择一个组件开始
- 测量并设置尺寸、边框半径和定位
- 选择颜色并创建背景渐变
- 堆叠多个背景渐变来创建深度
- 添加阴影和高光
- 重复直到满意为止
最终结果
完整代码可在CodePen、GitHub和Glitch上找到。打开、检查并试用一下。修改一些值是了解每个组件功能的最佳方法。
更多阅读材料
向我展示你的结果!
如果您按照本教程创建了自己的图像,我很乐意看到最终结果,您可以在 Twitter ( @liatrisbian )、Dev ( @fossheim )、CodePen ( @fossheim ) 或 GitHub ( @sarahfossheim ) 上标记我。
如果您想要额外的挑战,这里有一些有趣的交互可以添加到我现有的代码中:
- 单击红色快门使闪光灯亮起
- 使用其中一个开关创建“夜间模式”,将主体颜色从白色变为黑色
- 打印图片
- 通过旋转镜头来移动焦点