复杂 CSS 插图的建议
时间和练习
追踪是完全可以接受的
注意响应能力
三思而后行
对所有事物使用绝对定位
坚持一种方法
保持风格的稳固结构
处理不规则形状
clip-path 是你的朋友
border-radius 是你的另一个朋友
阴影技术
预处理器非常有用
就是这样!
如果你问我关于前端开发最常听到的问题是什么,我会说是“如何提高 CSS 水平?”。这个问题通常是在我分享自己制作的 CSS 插图后提出的。我很喜欢在 CodePen 上分享这些内容。
对很多人来说,CSS 就像一头无法驯服的神秘野兽。Chris的这条推文让我忍不住笑了出来,因为虽然听起来很讽刺,但其中却不乏道理。话虽如此,如果我告诉你,你只需要掌握一些属性和技巧,就能创造出任何你想要的东西,你会怎么想?事实是,你确实离它很近了。
我一直想写一篇类似的文章,但这个话题很难涵盖,因为可能性和技巧太多,通常有不止一种方法可以完成同一件事。CSS 插图也是如此。它没有正确或错误的方法。我们都在使用同一个画布。只是有很多不同的工具可以将这些像素绘制到页面上。
虽然 CSS 插图没有“一刀切”的方法,但我可以提供一套可能对您的旅程有所帮助的技术。
时间和练习
CSS 插图需要大量的时间和练习。你追求的越精确,插图越复杂,花费的时间就越长。耗时的部分通常不是决定使用哪些属性以及如何使用,而是不断修改,让它们看起来正确。准备好熟悉浏览器开发工具中的样式检查器吧!如果你还没用过VisBug,我也推荐你试试。
Ben Evans 和 Diana Smith 是两位出色的 CSS 艺术家。他们最近都谈到了 CSS 插画创作的时间消耗。
我发布了一张关于杯子的表情包图片,Ben 的回复完美地总结了这一切:
当我第一次看到这条推文时,我很想用 CSS 创建它,但后来想到我的回复大约需要一个月的时间。
这需要时间!
追踪是完全可以接受的
我们通常对想要展示的内容有一个想法。毕竟,这篇文章不是关于设计的。它讲的是如何使用 DOM 和 CSS 渲染图像。我确信这项技术自古以来就存在。不过,最近几个月我一直在分享它。
- 查找或创建您想要说明的图像。
- 使用标签将其拉入您的 HTML
<img>
。 - 将其放置在能够位于插图下方的位置。
- 降低图像不透明度,使其仍然可见但不会太过明显。
- 使用 DOM 来追踪它。
令我惊讶的是,这项技术并不常见。但它对于创建精确的 CSS 插图来说非常有价值。
看看这个技巧的实际效果:
![]()
![]()
Jhey🐻@jh3yy
这是创建 CSS @eggheadio的延时摄影😎
在🛠️之后使用 clip-path 调整了阴影
💻codepen.io /jh3y/ pen/rNOzY……通过@CodePen
#webdev #coding #CSS #animation #webdesign #design #creative #100DaysOfCode #HTML #Timelapse twitter.com/jhooks/status/…2020年5月1日下午17:55Joel🍄 @jhooks这个 css @jh3yy 与我分享了😍 https://t.co/GdpXMUimid
请在这里尝试一下:
注意响应能力
如果本文中有两种值得借鉴的技巧,那就是上面的“追踪”和下一个。
市面上有很多很棒的 CSS 插画示例。但遗憾的是,其中一些示例在小屏幕上缺乏样式,甚至无法显示。我们生活在一个科技产品第一印象至关重要的时代。不妨以一个用 CSS 绘制的键盘为例。有人偶然发现了你的作品,在智能手机上打开,却只看到了一半或一小部分插图。他们可能错过了演示中最精彩的部分!
这是我的诀窍:利用视口单位来绘制插图并创建您自己的缩放单位。
对于尺寸和定位,您可以选择使用缩放单位或百分比。这在需要使用框阴影时尤其有用,因为该属性接受视口单位,但不接受百分比。
以我上面创建的CSS egghead.io徽标为例。我找到了想要使用的图像,并用一个img
标签将其弹出到 DOM 中。
<image src='egghead.png'/>
img {
height: 50vmin;
left: 50%;
opacity: 0.25;
position: fixed;
top: 50%;
transform: translate(-50%, -50%);
}
高度50vmin
是 CSS 插图的期望尺寸。降低不透明度使我们能够在绘制过程中清晰地“追踪”插图。
然后,我们创建一个缩放单位。
/**
* image dimensions are 742 x 769
* width is 742
* height is 769
* my desired size is 50vmin
*/
:root {
--size: 50;
--unit: calc((var(--size) / 769) * 1vmin);
}
确定了图像尺寸后,我们就可以创建一个统一的单位,它会随着图像的缩放而变化。我们知道高度是最大的单位,所以我们以高度为基数来创建一个分数单位。
我们得到如下结果:
--unit: 0.06501950585vmin;
这看起来有点别扭,不过相信我,没关系。我们可以用它来调整插图容器的大小calc()
。
.egg {
height: calc(769 * var(--unit));
position: relative;
width: calc(742 * var(--unit));
z-index: 2;
}
如果我们使用百分比或新的--unit
自定义属性来设置 CSS 插图容器内的元素样式,我们将获得响应式 CSS 插图……而这只需要使用 CSS 变量进行几行数学运算!
调整此演示的大小,您将看到所有内容始终保持比例,并用作50vmin
尺寸约束。
三思而后行
另一个技巧是测量。哎呀,如果你要测量实物,你甚至可以拿卷尺测量!
这看起来可能有点奇怪,但我测量了这个场景。这是我客厅里的电视组合单元。这些测量值以厘米为单位。我用这些值根据电视的实际高度得到了一个响应式单元。我们可以给这个数字——以及所有其他数字——起一个容易记住其用途的名称,这要归功于自定义属性。
:root {
--light-switch: 15;
--light-switch-border: 10;
--light-switch-top: 15;
--light-switch-bottom: 25;
--tv-bezel: 15;
--tv-unit-bezel: 4;
--desired-height: 25vmin;
--one-cm: calc(var(--desired-height) / var(--tv-height));
--tv-width: 158.1;
--tv-height: 89.4;
--unit-height: 42;
--unit-width: 180;
--unit-top: 78.7;
--tv-bottom: 114.3;
--scaled-tv-width: calc(var(--tv-width) * var(--one-cm));
--scaled-tv-height: calc(var(--tv-height) * var(--one-cm));
--scaled-unit-width: calc(var(--unit-width) * var(--one-cm));
--scaled-unit-height: calc(var(--unit-height) * var(--one-cm));
}
一旦我们计算出一个变量,就可以在任何地方使用它。我知道我的电视158.1cm
又宽又89.4cm
高。我查过手册。但在我的 CSS 插图中,它总是会缩放到25vmin
。
对所有事物使用绝对定位
这条规则能帮你省去不少敲击键盘的麻烦。通常情况下,你会希望元素能够绝对定位。省省力气,把这条规则放在某个地方吧。
/* Your class name may vary */
.css-illustration *,
.css-illustration *:after,
.css-illustration *:before,
.css-illustration:after,
.css-illustration:before {
box-sizing: border-box;
position: absolute;
}
您的键盘会感谢您!
定位是 CSS 中一个比较棘手的概念。您可以阅读 CSS 年鉴,了解更多关于如何使用它的信息。
或者,玩一下这个小型定位游乐场:
坚持一种方法
这是迄今为止最难的事情。你该如何处理 CSS 插图?你该从哪里开始?你应该从最外层开始,然后再逐步深入吗?那样不太好。
你很可能会尝试一些方法,最终找到更好的方案。你肯定会反复尝试,但练习得越多,你就越能发现规律,并找到最适合自己的方法。
我倾向于将我的方法与创建矢量图形(插图由多个图层组成)联系起来。如果需要,可以将其拆分并在纸上绘制草图。但是,要从底部开始,然后逐步向上。这通常意味着先绘制较大的形状,然后再绘制更精细的细节。当需要移动元素时,您可以随时调整堆叠索引。
保持风格的稳固结构
这引出了我们关于结构的问题。尽量避免在插图中使用扁平的 DOM 结构。保持元素原子化可以更轻松地移动插图的各个部分。这也使得显示和隐藏插图的各个部分,甚至稍后为其添加动画变得更加容易。以 CSS Snorlax 演示为例。手臂、脚、头等都是独立的元素。这使得为手臂添加动画比我尝试将它们放在一起要容易得多,因为我可以直接将动画应用于类.snorlax__arm-left
。
这是我创建演示的延时镜头:
![]()
![]()
Jhey🐻@jh3yy
尝试将我们昨晚制作的 CSS Snorlax 的延时摄影组合在一起😅
回看真有趣!
💻codepen.io /jh3y /pen/yLYXV… via @CodePen
#webdev #coding #HTML #CSS #webdesign #100DaysOfCode #creative #design #animation2020年4月28日下午6:50
处理不规则形状
有一篇关于 CSS-Tricks 的文章非常精彩,教你如何使用 CSS 创建形状。但是,对于那些比较“别扭”的形状,比如长曲线,甚至是外曲线,该怎么办呢?在这种情况下,我们需要打破常规。诸如overflow
、border-radius
、 和 之类的属性clip-path
会非常有帮助。
参考这个 CSS Jigglypuff 演示。切换复选框。
这就是创建曲线形状的关键!我们有一个比主体大得多的元素,并border-radius
应用了 。然后我们将其应用overflow: hidden
到主体上,以截断该部分。
我们如何创建外曲线?这个有点棘手。但我喜欢用的一个技巧是transparent
使用粗边框元素。然后应用一个border-radius
,并根据需要剪掉多余的部分。
如果你点击切换按钮,它会显示我们用来跨越那个角的元素。另一个技巧是叠加一个与背景颜色匹配的圆圈。在我们需要更改背景颜色之前,这样做是没问题的。如果你有一个变量或其他东西来表示该颜色,那就没问题了。但是,这可能会使维护变得有点困难。
clip-path 是你的朋友
你可能已经注意到上一个演示中几个有趣的 CSS 属性,包括clip-path
。如果你想创建复杂的 CSS 形状,你很可能需要 clip-path 。当隐藏父框溢出无法满足需求时,它对于截断元素部分尤其有用。
这是我之前制作的一个小演示,展示了不同的clip-path
可能性。
还有这个演示,它采用了“CSS 的形状”文章中的想法并用 重新创建clip-path
。
border-radius 是你的另一个朋友
你需要使用border-radius来创建曲线。一个不常见的技巧是使用“double”语法。这样你就可以为每个角创建水平和垂直半径。
玩一下这个演示,真正体会一下的威力border-radius
。我主张全面使用百分比,以保持响应速度。
阴影技术
所有形状都画好了,布局也合理,颜色也都到位了……但还是有地方看起来不对劲。很可能是缺少阴影。
阴影增加了深度,营造出一种逼真的感觉。不妨看看这张 Gal Shir 插画的复刻版。Gal 非常擅长运用阴影和渐变来创作精美的插画。我觉得重新创作一下,并添加一个可以切换阴影的开关,看看效果会很有趣。
box-shadow
阴影效果通常由和组合产生background-image
。
这些属性的关键在于,我们可以将它们堆叠在一个逗号分隔的列表中。例如,演示中的大锅就包含一个用于整个身体的渐变列表。
.cauldron {
background:
radial-gradient(25% 25% at 25% 55%, var(--rim-color), transparent),
radial-gradient(100% 100% at -2% 50%, transparent, transparent 92%, var(--cauldron-color)),
radial-gradient(100% 100% at -5% 50%, transparent, transparent 80%, var(--darkness)),
linear-gradient(310deg, var(--inner-rim-color) 25%, transparent), var(--cauldron-color);
}
请注意,这里使用的radial-gradient()
和 alinear-gradient()
并不总是使用精确的整数值。同样,这些数字是没问题的。事实上,你会花很多时间在样式检查器中调整和修改它们。
它和box-shadow 的作用基本相同。然而,我们也可以用它inset
来创建复杂的边框和额外的深度。
.cauldron__opening {
box-shadow:
0 0px calc(var(--size) * 0.05px) calc(var(--size) * 0.005px) var(--rim-color) inset,
0 calc(var(--size) * 0.025px) 0 calc(var(--size) * 0.025px) var(--inner-rim-color) inset,
0 10px 20px 0px var(--darkness), 0 10px 20px -10px var(--inner-rim-color);
}
当然,有时使用filter:drop-shadow()来获得您想要的效果会更有意义。
Lynn Fisher 的a.singlediv.com 网站就是这些属性应用的一个绝佳范例。不妨浏览一下这个网站,看看其中的一些插图,了解一下如何在插图中巧妙地运用box-shadow
它们。background-image
box-shadow
它非常强大,你可以用它来创作整幅插画。我曾经开玩笑说要用 CSS 创作一美元的插画。
Jhey🐻@jh3yy
用 CSS 写对吧?😅
#webdev #CSS #animation #webdesign #coding #100DaysOfCode #HTML twitter.com/jackbutcher/st…2020年4月22日上午11:38杰克·布彻@jackbutcher一个可以改变你生活的小目标:在互联网上赚 1 美元。https://t.co/JPlJypuA4U
我使用一个生成器来创建带有单个 div 的插图。但是 Alvaro Montoro更进一步,他编写了一个生成器来代替 div 来实现这个功能box-shadow
。
预处理器非常有用
虽然预处理器并非必需,但使用它们可以帮助保持代码简洁。例如,Pug 可以加快 HTML 编写速度,尤其是在使用循环处理大量重复元素时。这样,我们就可以限定 CSS 自定义属性的范围,只需定义一次样式,然后在需要的地方覆盖它们。
下面是另一个演示 DRY 结构的示例。花朵使用相同的标记构造,但每个花朵都有自己的索引类,用于应用作用域 CSS 属性。
第一朵花具有以下特性:
.flower--1 {
--hue: 190;
--x: 0;
--y: 0;
--size: 125;
--r: 0;
}
这是第一个,所以其他所有花都基于它。注意第二朵花的位置稍微偏右上。只需为相同的自定义属性分配不同的值即可:
.flower--2 {
--hue: 320;
--x: 140;
--y: -75;
--size: 75;
--r: 40;
}
![]()
![]()
Jhey🐻@jh3yy
最新的 CodePen Spark 中出现了动画响应式 CSS Leif!✨
对于那些不了解《动物森友会》的玩家来说,Leif 是一只热爱园艺的树懒,它会造访你的岛屿 🌻
这是一段延时摄影!📹
💻 codepen.io/spark/181 via @CodePen2020年5月19日 晚上9点24分
就是这样!
继续吧,运用这些技巧,提出你自己的,分享它们,并分享你的 CSS 杰作!嘿,如果你有自己的建议,也请分享!这绝对是通过大量尝试和错误才能学到的东西——对我有用的方法可能与对你有用的方法不同,我们可以从这些不同的方法中学习。
鏂囩珷鏉ユ簮锛�https://dev.to/jh3y/advice-for-complex-css-illustrations-2di0