🔥 从最近流行的一幅 CSS 风景画中学习 2 个知识点

最近 CodePen 流行的一张用纯 CSS 绘制的风景画令人印象深刻:

天空的眩光,睡眠反射,精细的房屋细节相当惊艳,下面我们大致说一说这张图片中的一些技术细节。图画的源码地址在文末。

分析

观察图像,结合源码 HTML 的二级节点可以知道,整个画面大致由天空、阳光、房屋、海岸、海面、水面的栏杆、水中的太阳组成。通过观察可以发现画面上有许多重复的元素,比如水面的横线、远处房屋的窗户。猜测作者使用了重复的元素来构成图形。类似以往我们在其他项目见过一些 非 Canvas、非 SVG 作画,它们不外乎都是使用节点进行定位,然后再使用 CSS 样式绘制,最后组合成一张图片。

我们可以使用这两种比较便捷的方法,查看指定元素:

  • 通过 ctrl+shift+c 我们可以快速定位到相关元素。
  • 把相关节点的透明度设为 0,或者调整其背景颜色,查看它在画面中的表现。

多重阴影

先从看面横线开始。定位到该元素的节点。取消其 transform 属性。能看出它是由两种颜色的、多组长度的圆角矩形组成的,如下图:

再定位父元素的 ::before::after 伪元素,查看控制台的样式面板,可以知道横线是由 box-shadow 属性绘制的,如下图:

使用 box-shadow 画图其实是常见操作了,主要是利用其两点特性:

*可以通过逗号分隔实现多组输入(比如某些场景下 DIV 多边框就是这么做的) *可以精准的控制其大小、位移、颜色等属性

有一点要注意,节点的形状决定了其阴影的形状。也就是说,如果你的节点是方形,那么 Box-Shadow 就是方形,这是一个示例

大致总结一下,使用父元素进行形变和定位,然后通过父元素的 ::after ::before 两种伪元素的 box-shadow 绘制两种不同颜色的线条,这就是海面横线的绘制思路。其实其它图案也是这种定位+样式的思路画出来的,我们以这栋房屋举例:

  • 屋顶:父元素 border-bottom + 父元素 ::before
  • 窗户: 父元素 ::after

这幅画中其它图形基本上用的都是这种思路,就在此略过了。

多重背景

现在我们看到水面纹理(也就是水面那些点点),它是使用 background-image 属性进行绘制的:

通过 background-repeat 属性可以创建出重复的背景图案。而在这幅图片中,点与点在竖向排列是有偏移的,所以看起来像是斜着排列。达到这种效果只需要通过逗号分隔来给 background-image 设置多重背景就可以了,同时,background-size 也可以由逗号分隔开,分别设置每一个背景的偏移量。下段代码是一个示例:

.example {
  background-image:
  background-size: 1rem 1rem;
  background-position: 0 0, .5rem .5rem;
  background-image: radial-gradient(red 20%, rgba(255, 255, 255, 0) 0), radial-gradient(red 20%, rgba(255, 255, 255, 0) 0);
}

结果如下:

通过结合 background-imageblend-mode、渐变等各种可玩的东西,能创造出超多漂亮图案,如示例

一些细节补充

水面纹理的消失

细心的同学应该发现了,水面纹理在接近太阳倒影的地方,看起来像逐渐消失了一样:

这是因为接近太阳倒影的地方,作者加了一层颜色与水面纹理颜色相同的渐变。如果我们去掉这层渐变,就会发现“逐渐消失”其实是一种错觉,水面纹理一直存在:

太阳及其炫光

有一个需要注意的细节是,太阳本身在 z 轴的位置与房屋相比要离我们远一些,而太阳的炫光却展示在了房屋前面。这是一个 DOM 节点位置的特殊处理。

相关代码细节就大致如此了,谁代我问问作者的手是在哪儿买的呀?

图像分解

后语

源码地址在此:源码地址

阅读更多

脑洞再大一些:

  • 当节点只占一个像素的时候,我们就可以通过多重阴影可以画出任何图像了... 咳咳... 性能杀手,见这位老哥的示例:box-shadow-image-generator
  • 在使用节点定位+样式绘制的思路中,如果有规律的组合节点及其样式,也就是说如果将重用的思想发挥到极致的话... (  o=^•ェ•)o 也有这种项目:CSS-doodle

帅气的程序哥哥,漂亮的设计姐姐们,点个赞再走呗 o( ̄ ▽  ̄)o明示点赞

欢迎来踩我的博客:原文地址

原文链接:juejin.im

上一篇:Vue原理(一)
下一篇:tiny-json-http

相关推荐

  • 🔥手写大厂前端知识点源码系列(上)

    如今前端攻城狮的要求越来越高,会使用常见的API已经不能满足现如今前端日益快速发展的脚步。现在大厂基本都会要求面试者手写前端常见API的原理,以此来证明你对该知识点的理解程度。

    7 个月前
  • 💫 CSS 幻术 | 抗锯齿

    前言 传统网页的呈现是基于像素单位的,所以图片不能和 SVG 一样进行任意尺寸缩放后还保持边缘平整。也就是说,放大像素逻辑的图片,必然导致可视质量下降(信息失真)。

    5 个月前
  • 💖CSS + JS 送学妹满屏幕小爱心

    故事开始 午饭时间,暗恋已久的学妹拉着我的衣袖:“学长学长,你能不能让这些爱心变成五颜六色的吗~”。 我在旁边笑开了花~~~ 诶呀,口水流出来了。

    6 个月前
  • (译)CSS 定位与层叠上下文(Stacking context)

    你是否在使用定位时,会遇到一个定位元素即使设置更高的层级,也无法将另一个定位元素覆盖的情况?通过理解层叠上下文,你就能更好的构建你的应用。理解渲染流程和层叠顺序当浏览器将 HTML 解析成 DOM 结...

    1 个月前
  • 黑魔法之 CSS Entry

    大家都知道 webpack 的 Entry 都是 js,如果想输出 css 文件只能在 js 文件里导入 css,所以很多人都会想要是 entry 也可以是 css 那多好,这样就可以任意输出 cs...

    2 年前
  • 高级前端知识点汇总

    高级前端知识点汇总 1.首屏加载优化 2.搜索引擎优化(SEO) 3.请求优化 4.Vue服务器端渲染 (SSR) 5.W3C标准 6.vue render优化...

    8 个月前
  • 高度等于动态宽度(CSS流体布局)[复制品]

    web-tikiThomas Norman提出了一个问题:Height equal to dynamic width (CSS fluid layout) [duplicate],或许与您遇到的问题类...

    3 年前
  • 面试题CSS盒子模型,左右固定宽度,中间自适应的五种死法

    面试题目 假设高度已知,请写出三栏布局,左右300px,中间自适应 有几种方法呢? 最容易的应该想到利用float来写,代码如下 css样式代码,以下五种都是用一个样式代码 <sectio...

    2 年前
  • 面试知识点之javascript中变量与函数重名规则

    声明 相信大家都知道变量提升,函数提升,可重名的时候又是如何处理? 试问一下2个场景的输出值分别多多少? 情景一 console.log(a); var a = 100; function a...

    9 个月前
  • 面试必备!webpack 中那些最易混淆的 5 个知识点

    前两天为了优化公司的代码打包项目,恶补了很多 webpack4 的知识。要是放在几年前让我学习 webpack 我肯定是拒绝的,之前看过 webpack 的旧文档,比我们内部项目的文档还要简陋。

    1 年前

官方社区

扫码加入 JavaScript 社区