朋友,你听说过 CSS3 Mask 这个属性吗?
没听说过?不是很了解?
没关系,听我娓娓道来。
1. Mask 介绍
css遮罩是2008年4月由苹果公司添加到webkit引擎中的。遮罩提供一种基于像素级别的,可以控制元素透明度的能力,类似于png24位或png32位中的alpha透明通道的效果。
2012年11月15号,遮罩第一次出现在W3C公布的草案中。但是跟苹果公司的是不同的版本。
摘录自: http://www.w3cplus.com/css3/css-masking.html
当前(2016.10.19)mask
处于 候选标准阶段(CR),还不是正式标准(REC),webkit/blink 内核加前缀 -webkit-
可使用。
1.1 Mask 的兼容性
以下是来自 caniuse的统计:
ie/edge 全面不支持,Android 和 iOS Safari 阵营几乎全线飘浅绿,意味着支持部分功能 。不过,Android 4.0 及以下版本的对 mask
的兼容性并不友好!多亏了近几年智能手机市场的良(e)性竞争,给移动前端制造了一个相对良好的环境,以下是 Android 各版本的市场占用率:
Android 4.0 以下版本的占有率不足 **5%**,已不在主流测试机型内可以忽略不计。
1.2 Mask 的原理
蒙板可以是 CSS3 渐变或者半透明的PNG图片,蒙板元素的alpha值为0的时候会覆盖下面的元素,为1的时候会完全显示下面的内容。如下:
1.3 Mask 的发展
到目前为止,mask 在 W3C 上一共有6个版本(5个草案+1候选标准),如下:
W3C Working Draft 15 November 2012
W3C Working Draft 20 June 2013
W3C Last Call Working Draft, 29 October 2013
W3C Working Draft, 13 February 2014
W3C Last Call Working Draft, 22 May 2014
W3C Candidate Recommendation, 26 August 2014
当前 -webkit-mask
的标准基本上等同于第一个WD(草案)。(有理由相信『W3C Working Draft 15 November 2012』参考了 webkit.org 的 『 CSS Masks』)
1.4 Mask 语法
Definitions of CSS properties and values in this specification are analogous to definitions in CSS Backgrounds and Borders [CSS3BG].
摘录自: https://www.w3.org/TR/css-masking-1/#terminology
按 W3C 官网的说法,mask
的语法与 background
是相仿的。以下是 mask 与 background 属性的对照表:
mask
background
mask-clip
background-clip
*mask-composite
-
mask-image
background-image
*mask-mode
-
mask-origin
background-origin
mask-position
background-position
mask-repeat
background-repeat
mask-size
background-size
-
background-attachment
-
background-color
上表中,mask 与 background 对应的六个属性在 webkit/blink 内核都能完全支持,并且与W3C的标准保持一致,语法与 background
相通。background 的语法不赘述。
另外两个属性的情况如下:
mask-mode
当前没有任何浏览器支持。-webkit-mask-composite
属性值与W3C不同, 参见:『 -webkit-mask-composite - CSS | MDN』与 『mask-composite - CSS | MDN』
2. 图标的一个便捷选项
图标的主流方案有两种:Icon-Font 和 SVG Sprite。凹凸实验室推荐使用 SVG Sprite,具体参见 @高大师 的大作『 拥抱Web设计新趋势:SVG Sprites实践应用』。
笔者看来,这两种方案存在一个前提:图标必须是矢量图。这其实是道门槛,不是所有团队/个人都跨得过去的。
本节将介绍一个低成本的方案:Mask Icon
2.1 Mask Icon
素材icon.png :
SASS源码:
// 生成 黑、红、黄、蓝四个 icon。.icon {
display: inline-block;
width: 30px;
height: 30px;
background-color: black; // 控制图标的颜色
-webkit-mask: url(images/icon.png) 0 0 no-repeat;
-webkit-mask-size: 100% 100%;
&.red {
background-color: red;
}
&.yellow {
background-color: yellow;
}
&.blue {
background-color: blue;
}}
HTML源码:
<div class="icon"></div><div class="icon red"></div><div class="icon yellow"></div><div class="icon blue"></div>
截图如下:
使用起来跟 Icon-Font 是很类似,不过 mask
方案是通过 background-color
控制 icon 颜色,而 Icon-Font 是通过 color
。 color
比 background-color
有优势,它可以继承当前文本的色值,而 background-color 却无法继承文本色值(因为继承当前文本的背景色等同于透明)。
2.2 Mask Icon improve
能实现通过 color
来改变 mask
icon 的颜色吗?
大神张鑫旭在『currentColor-CSS3超高校级好用CSS变量』给出了答案:currentColor。
p {
margin: 0;
padding: 10px;
color: #000;
font-size: 14px;}.icon {
display: inline-block;
width: 15px;
height: 15px;
background-color: currentColor; // 控制图标的颜色 - 默认当前color值
-webkit-mask: url(images/icon.png) 0 0 no-repeat;
-webkit-mask-size: 100% 100%;}.red {
color: red;}.yellow {
color: yellow;}.blue {
color: blue;}
<p>这个是黑色icon<span class="icon"></span></p><p class="red">这个是红色icon<span class="icon"></span></p><p class="yellow">这个是黄色icon<span class="icon"></span></p><p class="blue">这个是蓝色icon<span class="icon"></span></p>
通过改进mask 图标几乎可以取代 Icon-Font。
测试DEMO:
2.3 Mask Icon 的局限
浏览器兼容是 CSS3 Mask
的最大局限,以 mask-image
为例,浏览器的支持情况如下:
PC端:
移动端:
webkit 两兄弟支持 mask-image
,而 firefox 和 ie/edge 需要通过 SVG Mask 来实现蒙层。
移动端 ≈ Android + iOS, Mask Icon
可当作为移动端的一个便捷方案。
3. 多蒙层介绍
The mask of a box can have multiple layers. The number of layers is determined by the number of comma-separated values in the ‘mask-image’ property.
摘录自:https://www.w3.org/TR/2012/WD-css-masking-20121115/#layering
按W3C的定义,mask 可设置多蒙层 。由于缺少多蒙层的兼容性数据,笔者做了一个简单的例子来检验多蒙层在不同机型下的表现。
目标图形:
素材:
测试用机:
iPhone 6/6+(iOS 10)、 荣耀3c(Android 4.2.2)、 红米(Android 4.4.4 )、魅蓝(Android 4.4.4) 三星GT-I9300(Android 4.3)、Microsoft Limia RM-1090(windows mobile)
测试代码如下:
.seckill_coupon {
width: (718px / 2);
height: auto;
margin: 0 auto;
font-size: 0;
font-family: Helvetica;
&_item {
width: (226px / 2);
height: ( 120px / 2 );
display: inline-block;
-webkit-mask-image: url(images/seckill_coupon_ellipsis.png?__inline), url(images/seckill_coupon_100px.png?__inline), url(images/seckill_coupon_ellipsis.png?__inline);
-webkit-mask-position: (190px / 2) -5px, 0 5px, (190px / 2) 55px;
-webkit-mask-repeat: repeat-x, no-repeat, repeat-x;
-webkit-mask-size: (750px / 2) auto, (750px / 2) auto, (750px / 2) auto;
&_top {
background: #f2f7f7 linear-gradient(to bottom, #fafcfc, #f2f7f7);
border-radius: 3px 3px 0 0;
height: ( 70px / 2 );
width: 100%;
}
&_bottom {
width: 100%;
height: ( 50px / 2 );
border-radius: 0 0 3px 3px;
background-image: linear-gradient(to bottom, #ff9600, #ff7c00);
}
}}
<div class="seckill_coupon">
<span class="seckill_coupon_item">
<div class="seckill_coupon_item_top">
</div>
<div class="seckill_coupon_item_bottom">
</div>
</span></div>
测试结果:
设备
浏览器
支持度
截图
iPhone 6/6+
(iOS 9/10)
Safari/WeChat
支持
魅蓝
(Android 4.4.4)
WeChat 6.3.25
支持
魅蓝
(Android 4.4.4)
原生浏览器
支持
红米
(Android 4.4.4)
WeChat 6.3.25
支持
红米
(Android 4.4.4)
原生浏览器
支持
三星GT-I9300
(Android 4.3)
WeChat 6.3.25
支持
三星GT-I9300
(Android 4.3)
原生浏览器
不友好
荣耀3c
(Android 4.2.2)
WeChat 6.3.25
支持
荣耀3c
(Android 4.2.2)
原生浏览器
不友好
Lumia RM-1090
(windows mobile)
ie
不支持
测试解读:
虽然测试的机型不多,但仍然可以看出 Android 4.3及以下版本原生浏览器对多蒙层的支持不友好,windows mobile是 不支持,而使用 X5
内核的 WeChat 6.3.25对多蒙层的支持度是良好的。
将 取消多蒙层 视作 多蒙层的降级以处理不友好的机型:
-- 降级 ->
通过 @supports
来做降级处理:
@supports (-webkit-mask-repeat: repeat) {
-webkit-mask-image: url(images/seckill_coupon_ellipsis.png?__inline), url(images/seckill_coupon_100px.png?__inline), url(images/seckill_coupon_ellipsis.png?__inline);
-webkit-mask-position: (190px / 2) -5px, 0 5px, (190px / 2) 55px;
-webkit-mask-repeat: repeat-x, no-repeat, repeat-x;
-webkit-mask-size: (750px / 2) auto, (750px / 2) auto, (750px / 2) auto;}
不过,使用 @supports 后,(荣耀3c与三星 GT I9300的)X5内核也被降级,这并不是最理想的结果。以下是测试DEMO:
(未使用 @supports 降级)
(使用 @supports 降级)
测试结论
微信手Q平台,使用多蒙层是友好的
非X5内核平台,目前不建议多蒙层
4. Mask border image 介绍
在实际项目中,笔者经常使用 border-image
来实现 background 没办法简单实现的需求。mask 有一个 mask-border
的成员与 border-image 相对应,具体可参见:https://www.w3.org/TR/css-masking/#mask-borders。
现阶段(2016.10.19),未有任何主流浏览器直接支持 mask-border,因为在 mask 草案(WD)的漫长修改过程中,mask-border 经历了两次名称的变更,具体过程如下:
W3C Working Draft 15 November 2012 -- mask-box-image
W3C Working Draft 20 June 2013 -- mask-box-image
W3C Last Call Working Draft, 29 October 2013 -- mask-box-image
W3C Working Draft, 13 February 2014 -- mask-box
W3C Last Call Working Draft, 22 May 2014 -- mask-border
W3C Candidate Recommendation, 26 August 2014 -- mask-border
这个过程与 flex
是相似的。
当前 webkit/blink 内核 (Chrome/Safari)采用了第一个WD(草案)的 mask-box-image
。不过,mask-border
代表了未来,所以在写 css 时少不了兼容的代码,这个后面会介绍到。
4.1 Mask-border 的语法
The syntax of mask-border corresponds to the border-image property of CSS Background and Borders [CSS3BG].
摘录自: https://www.w3.org/TR/css-masking-1/#mask-borders
**为了方便描述,本章的 mask-border 都是指 mask-box-image ,读者自觉替换*
mask-border 与 border-image 的对照列表如下:
mask-border
border-image
mask-border-source
border-image-source
*mask-border-mode
-
mask-border-slice
border-image-slice
mask-border-width
border-image-width
mask-border-outset
border-image-outset
mask-border-repeat
border-image-repeat
mask-border-mode
是在『 W3C Last Call Working Draft, 22 May 2014 』才出现的属性,当前没有任何浏览器支持 ,所以 mask-border 与 border-image 在语法上是完全相通!理解了 border-image就理解了 mask-border 。border-image 的具体使用可以参考MDN的『border-image - CSS | MDN』,这里也不赘述。
4.2 Mask-border 的兼容写法
如果是手写 css 的同学,在使用 mask-border 需要注意代码的兼容性。其实很简单如下:
// 当下标准-webkit-mask-box-image-source: url(images/seckill_coupon_half.png?__inline);-webkit-mask-box-image-slice: 9 44 9 1 fill;-webkit-mask-box-image-width: 5px 23px 5px 5px;-webkit-mask-box-image-repeat: stretch stretch;// 兼容未来mask-border-source: url(images/seckill_coupon_half.png?__inline);mask-border-slice: 9 44 9 1 fill;mask-border-width: 5px 23px 5px 5px;mask-border-repeat: stretch stretch;
如果是使用 sass
、less
的同学,推荐安装 autoprefixer 插件。autoprefixer
可以为使用者解决 css 兼容写法的烦恼,有了它,mask-border 可以直接使用兼容未来写法:
// 在安装了 autoprefixer 后mask-border-source: url(images/seckill_coupon_half.png?__inline);mask-border-slice: 9 44 9 1 fill;mask-border-width: 5px 23px 5px 5px;mask-border-repeat: stretch stretch;
4.3 Mask-border 实例
上节多蒙层的例子使用 mask-border 来实现会更合适:
目标图形:
素材:
测试用机:
iPhone 6/6+(iOS 10)、 荣耀3c(Android 4.2.2)、 红米(Android 4.4.4 )、魅蓝(Android 4.4.4) 三星GT-I9300(Android 4.3)、Microsoft Limia RM-1090(windows mobile)
测试代码:
.seckill_coupon {
width: (718px / 2);
height: auto;
margin: 0 auto;
font-size: 0;
font-family: Helvetica;
&_item {
width: (226px / 2);
height: ( 120px / 2 );
display: inline-block;
mask-border-source: url(images/seckill_coupon_half.png?__inline);
mask-border-slice: 9 44 9 1 fill;
mask-border-width: 5px 23px 5px 5px;
&_top {
background: #f2f7f7 linear-gradient(to bottom, #fafcfc, #f2f7f7);
border-radius: 3px 3px 0 0;
height: ( 70px / 2 );
width: 100%;
}
&_bottom {
width: 100%;
height: ( 50px / 2 );
border-radius: 0 0 3px 3px;
background-image: linear-gradient(to bottom, #ff9600, #ff7c00);
}
}}
<div class="seckill_coupon">
<span class="seckill_coupon_item">
<div class="seckill_coupon_item_top">
</div>
<div class="seckill_coupon_item_bottom">
</div>
</span></div>
以下是测试DEMO:
测试结果:
设备
浏览器
支持度
截图
iPhone 6/6+
(iOS 9/10)
Safari/WeChat
支持
魅蓝
(Android 4.4.4)
WeChat 6.3.25
支持
魅蓝
(Android 4.4.4)
原生浏览器
支持
红米
(Android 4.4.4)
WeChat 6.3.25
支持
红米
(Android 4.4.4)
原生浏览器
支持
三星GT-I9300
(Android 4.3)
WeChat 6.3.25
支持
三星GT-I9300
(Android 4.3)
原生浏览器
支持
荣耀3c
(Android 4.2.2)
WeChat 6.3.25
支持
荣耀3c
(Android 4.2.2)
原生浏览器
支持
Lumia RM-1090
(windows mobile)
ie
不支持
测试结论mask-border
在移动端的兼容性很好,推荐使用。
5. 参考资料
CSS Masks
-webkit-mask-composite - CSS | MDN
mask-composite - CSS | MDN
CSS Masking Module Level 1
mask - CSS | MDN
拥抱Web设计新趋势:SVG Sprites实践应用
ICON-FONT图标字体的四类制作方法
currentColor-CSS3超高校级好用CSS变量
-webkit-mask-box-image - CSS | MDN
border-image - CSS | MDN
感谢您的阅读,本文由 凹凸实验室 版权所有。如若转载,请注明出处:凹凸实验室
本文分享自微信公众号 - 凹凸实验室(AOTULabs)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。