#lab-and-lch {
–ux-gray: lch(50% 0 0);
–rad-pink: lch(50% 200 230);
–rad-pink: lab(150% 160 0);
–pale-purple: lab(75% 50 -50);
}
另外,我们现在描述颜色都是在sRBG 色值空间,而颜色色值空间是一个复杂的体系,除了 sRGB 之外还有其他的色值空间,比如说 LCH:
正如上图所示,LCH 颜色空间的颜色数量要比 sRGB 颜色空间的多,而且描述的颜色更为细腻。
如上图所示,可以在color() 函数中指定颜色空间:
#color-function {
–rad-pink: color(display-p3 1 0 1);
–rad-pink: color(lab 50% 150 -50);
–rad-pink: color(srgb 100% 0% 50%);
}
注意,使用了color() 函数指定颜色空间除了要考虑该函数支持度(浏览器的兼容性)还需要考虑硬件设备对颜色空间的支持度。
在 CSS 中可以借助媒体查询 @media 来做相应的判断,比如下面的示例,如果终端设备支持的话,就会采用指定颜色空间的色值:
@media (dynamic-range: high) {
.neon-pink {
–neon-glow: color(display-p3 1 0 1);
}
.neon-green {
–neon-grow: color(display-p3 0 1 0);
}
}
更为强大的是 CSS 颜色模块 Level 5 版本,对颜色函数能力做了进一步的扩展。比如,可以在 rgb()、hsl() 、hwb() 、lab() 和 lch() 函数基础上添加 from 关键词,实现基于一个颜色的基础上,只对某个参数做调整:
rgb() = rgb([from ]? {3} [ / ]? ) | rgb([from ]? {3} [ / ]? )
hsl() = hsl([from ]? [ / ]? )
hwb() = hwb([from ]? [ / ]? )
lab() = lab([from ]? [ / ]? )
lch() = lch([from ]? [ / ]? )
复制代码
来看一个 hsl() 的示例:
上图展示的是,基于 --theme-primary (原色,即 hsl(274, 61%, 50%))颜色只对l 参数做调整,从 50% 调整到 30% ,从而获得一个新的颜色,即 hsl(274, 61%, 30%) 。使用这样的方式,我们就可以很轻易的获取基于某个颜色参数改变得来的颜色面板:
除此之外, 颜色模块 Level 5 版本还新增了一些新的函数用来描述颜色,比如 color-mix() 、color-contrast() 、color-adjust() 等:
.color-mix {
–pink: color-mix(red, white);
–brand: #0af;
–text1: color-mix(var(–brand) 25%, black);
–text2: color-mix(var(–brand) 40%, black);
}
.color-contrast {
color: color-contrast(
var(–bg)
vs
black, white
);
}
–text-on-bg: color-contrast(
var(–bg-blue-1)
vs
var(–text-subdued),
var(–text-light),
var(–text-lightest)
);
.color-adjust {
–brand: #0af;
–darker: color-adjust(var(–brand) lightness -50%);
–lighter: color-adjust(var(–brand) lightness +50%);
}
简单介绍一下这几个颜色函数。其中 color-mix() 函数接受两个 值,并在给定的颜色空间中以指定的数量返回它们混合的结果。如果没有特殊说明,否则在 lch() 颜色空间中进行混合。比如下图所展示的就是 在lch() 颜色空间(默认)中将 red 和 yellow 混合,每个 lch 通道的红色值占65%,黄色值占 35%,即 color-mix(red yellow 65%) :
color-contrast() 函数很有意思,它可以帮助我们提高Web可访问性方面的能力。其主要作用是获取一个颜色值,并将其与其他颜色值的列表进行比较,从列表中选择对比度最高的一个。
比如 color-contrast(white vs red, white, green) ,分别会拿 red 、white 和 green 与 white 对比,其中 green 与 white 对比度最高,最终会取 green 颜色:
color-adjust() 函数可用来在给定颜色空间中通过指定的变换函数对该颜色进行调整,除非另有规定,否则调整是在 lch() 色彩空间中进行的。比如 color-adjust(#0af lightness +50%) 是颜色 #0af 在 lch 颜色空间中高度增加 50% 。
也就是说,在不久的未来,这些颜色函数可以很好的帮助我们控制Web中的颜色值。因为这些颜色函数都已成为主流浏览器的实验性属性,特别是 Safari 浏览器,对这方面的支持度要高于 Chrome 和 Firefox 浏览器。
CSS 背景
CSS 的 background 属性是一个简写属性,这个对于大家来说再熟悉不过了。不过在这里着重想把 background-position 和 background-repeat 单独拿出来和大家聊聊。你可能会问,这两个属性又不是什么新属性了,有什么值得聊的呢?其实未必,这两个属性虽然老,但有几个小细节对于很多开发者来说还是会感到陌生的。咱们先从 backgroundd-position 开始。
▐ background-position
background-position 主要是用来指定背景图片在容器中的位置。大家较为熟悉的是,背景图片左上角(顶点)相对于容器左上角计算,如下图所示:
不过,有的时候,希望背景图片能相对于容器右侧边缘或底部边缘计算,比如下图:
要让背景图片距离容器右侧边缘和底部边缘都是 50px 。针对这样的场景,你或许首先会想到使用容器大小和背景图片大小进行计算,得出距离顶部和左侧边缘的距离,然后将计算出来的值运用于 background-position 中。当然,熟悉 CSS 的同学或许会想到使用 calc() 函数:
:root {
–xPosition: 50px;
–yPosition: 50px;
}
.container {
background-position: calc(100% - var(–xPosition) calc(100% - var(–yPosition)))
}
使用 calc() 动态计算要比通过容器和背景图片尺寸大小计算方便得多。
事实上呢?background-position 提供了另一种特性,我们可以通过关键词 top 、right 、bottom 和 left 来指定方向。比如我们熟悉的用法 :
background-position: 50px 50px;
// 相当于
background-position: top 50px left 50px;
那么,我们要实现上图的效果,就可以使用 right 和 bottom 关键词,让事情变得非常简单:
:root {
–xPosition: 50px;
–yPosition: 50px;
}
.container {
background-position: right var(–xPosition) bottom var(–yPosition);
}
最终效果如下:
Demo: codepen.io/airen/full/…
注,示例中左侧是使用 calc() 计算的效果,右侧使用的是关键词实现的效果。
background-position 使用还有一个小细节需要注意,即 background-position 采用百分比值。因为使用百分比值的 background-position 计算会相对于其他单位值复杂:
正如上图所示,背景图片原始尺寸是 100px x 100px ,容器的尺寸(使用该背景图片的元素)是 410px x 210px ,如果使用 background-position: 75% 50% 时,它的计算如下:
// background-position的x轴坐标
x = (容器宽度 - 背景图片宽度) x background-position的x坐标的百分比值 = (410 - 100) x 75% = 232.5px
// background-position的y轴坐标
y = (容器高度 - 背景图片高度) x background-position的y坐标的百分比值 = (210 - 100) x 50% = 55px
就该示例而言,background-position: 75% 50% 就相当于 bacckground-position: 232.5px 55px。
注意,如果我们把 background-size 和 background-position 取百分比值场景结合起来使用的时候,会让事情变得更为复杂,特别是background-size取值为cover 或contain 更会让你感到蛋疼。为什么会这样呢?这已经超出来这篇文章所要探讨的话题,如果你感兴趣的话,可以以此为课题,深入探讨一下。
▐ background-repeat
在 background-repeat 属性上除了可以使用我们熟悉的 no-repeat 和 repeat (或者 repeat-x 和 repeat-y) 之外还可以使用 round 和 space 。
我们都知道,使用 repeat 的时候,有可能会造成背景图片在平铺的时候被裁剪。如果希望背景图片在平铺时不被剪切,那么可以使用 round 来替代,它的最大特色就是背景图片在平铺的时候会根据容器的宽高对背景图片做相应的尺寸调整。而 space 会留出相应的空间,即在保证背景图片不被裁剪的情况之下,对多出来的空间以空白的方式在背景图片之间留出。
针对于这些值,我录制了一个简单的视频,从视频的展示效果中可以更好的看出它们之间的差异:
Demo: https://codepen.io/airen/full/mdWyOOj
CSS 蒙层和剪切
如果你对设计或设计软件较为熟悉的话,对于蒙层和剪切不会感到陌生。设计师在做一些设计稿的时候,时常也会用到蒙层和剪切的能力。随着 CSS 的发展,在 CSS 的世界中也有了这两个特性,它们在 W3C 的 《CSS Masking Module Level 1》规范中定义,主要的作用如下图所示:
可以灵活的控制内容的显示区域。
蒙层和剪切对应的 CSS 属性就是 mask 和 clip-path ,其中 mask 是一个简写属性,它的使用规则和 background 非常的相似。我将通过简单的示例来向大家展示它们能帮我们做些什么。
先看 mask :
Demo: https://codepen.io/airen/full/MdQrvR
视频中的 emoji 和文本残缺不全(看上去被啃了一样)。在没有mask 的能力之前,如果我们要实现这样的效果几乎是不太可能,现在有了之后,实现起来就非常的简单。我们只需要像下面这样的一张图片(用于mask-image 上的图片),即蒙层图:
h1 {
mask-image: url(mask.png);
}
复制代码
而且我们还可以借助 mask 的合成能力,让多个蒙层做合成运算:
运用蒙层相关的能力,可以快速帮助我们实现一些业务场景所需的效果:
除此之外还可以实现换肤的效果:
Demo: https://codepen.io/airen/full/yWvzYy
再来看剪切。在 CSS 中使用 clip-path 的能力,除了可以帮助我们控制好所要展示的区域之外,还可以结合不同的路径和函数值实现不规则的图形展示。比如 Clippy 所展示的效果:
比如在实际需求中,需要实现一些不规则,又是多状态下的 UI 效果,那么 clip-path 就会很方便:
而且使用clip-path 结合 transition 或 animation 可以在交互上做一些更好的动效:
左侧是原状态下效果,右侧是鼠标悬浮状态下效果:
Demo: https://codepen.io/airen/full/zYqbgRK
特别是,当clip-path 支持 path() 函数时,可以做得事情更多了,比如我们想要绘制一个心形的 UI 效果:
另外就是把 clip-path 、float 和 CSS 的 Shapes 结合可以实现一些不规则的图文混排的布局效果:
CSS 混合模式
CSS 混合模式是个很有意思的特性,目前主要有 mix-blend-mode 和 background-blend-mode 两个属性,前者是用于多个元素的合成,后者是用于多个背景的合成。使用它们可以实现一些特殊的效果,比如类似 Photoshop 中的滤镜效果:
采用混合模式特性,我们可以轻易的实现产品图换色的效果:
Demo: https://codepen.io/kylewetton/full/OJLmJoV
这里简单地介绍一下,这个效果是怎么实现的。
首先我们有一张类似下图的产品图:
通过 SVG 的能力,我们描绘图一个纯黑色的 SVG 形状,形状和上图的沙发是相吻合的:
描绘出来的 SVG 代码并不复杂: