剑客
关注科技互联网

CSS3 Mask 安利报告

朋友,你听说过 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 的统计:

CSS3 Mask 安利报告

ie/edge 全面不支持,Android 和 iOS Safari 阵营几乎全线飘浅绿,意味着支持部分功能 。不过,Android 4.0 及以下版本的对 mask 的兼容性并不友好!多亏了近几年智能手机市场的良(e)性竞争,给移动前端制造了一个相对良好的环境,以下是 Android 各版本的市场占用率:

CSS3 Mask 安利报告

Android 4.0 以下版本的占有率不足 5% ,已不在主流测试机型内可以忽略不计。

1.2 Mask 的原理

蒙板可以是 CSS3 渐变或者半透明的PNG图片,蒙板元素的alpha值为0的时候会覆盖下面的元素,为1的时候会完全显示下面的内容。如下:

CSS3 Mask 安利报告

1.3 Mask 的发展

到目前为止,mask 在 W3C 上一共有6个版本(5个草案+1候选标准),如下:

当前 -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 的语法不赘述。

另外两个属性的情况如下:

2. 图标的一个便捷选项

图标的主流方案有两种:Icon-Font 和 SVG Sprite。凹凸实验室推荐使用 SVG Sprite,具体参见 @高大师 的大作『 拥抱Web设计新趋势:SVG Sprites实践应用 』。

笔者看来,这两种方案存在一个前提: 图标必须是矢量图 。这其实是道门槛,不是所有团队/个人都跨得过去的。

本节将介绍一个低成本的方案: Mask Icon

2.1 Mask Icon

素材icon.png : CSS3 Mask 安利报告

SASS源码:

// 生成 黑、红、黄、蓝四个 icon。
.icon{
display: inline-block;
width:30px;
height:30px;
background-color: black;// 控制图标的颜色
 -webkit-mask: url(images/icon.png)00no-repeat;
 -webkit-mask-size:100%100%;
 &.red{
background-color: red;
 }
 &.yellow{
background-color: yellow;
 }
 &.blue{
background-color: blue;
 }
}

HTML源码:

<divclass="icon"></div>
<divclass="icon red"></div>
<divclass="icon yellow"></div>
<divclass="icon blue"></div>

截图如下:

CSS3 Mask 安利报告

使用起来跟 Icon-Font 是很类似,不过 mask 方案是通过 background-color 控制 icon 颜色,而 Icon-Font 是通过 colorcolorbackground-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)00no-repeat;
 -webkit-mask-size:100%100%;
}

.red{
color: red;
}
.yellow{
color: yellow;
}
.blue{
color: blue;
}
<p>这个是黑色icon<spanclass="icon"></span></p>
<pclass="red">这个是红色icon<spanclass="icon"></span></p>
<pclass="yellow">这个是黄色icon<spanclass="icon"></span></p>
<pclass="blue">这个是蓝色icon<spanclass="icon"></span></p>

CSS3 Mask 安利报告

通过改进mask 图标几乎可以取代 Icon-Font。

测试DEMO:

CSS3 Mask 安利报告

2.3 Mask Icon 的局限

浏览器兼容是 CSS3 Mask 的最大局限,以 mask-image 为例,浏览器的支持情况如下:

PC端:

CSS3 Mask 安利报告

移动端:

CSS3 Mask 安利报告

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 可设置多蒙层 。由于缺少多蒙层的兼容性数据,笔者做了一个简单的例子来检验多蒙层在不同机型下的表现。

目标图形:

CSS3 Mask 安利报告

素材:

CSS3 Mask 安利报告
CSS3 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:0auto;
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,05px, (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:#f2f7f7linear-gradient(to bottom,#fafcfc,#f2f7f7);
border-radius:3px3px00;
height: (70px/2);
width:100%;
 }
 &_bottom {
width:100%;
height: (50px/2);
border-radius:003px3px;
background-image: linear-gradient(to bottom,#ff9600,#ff7c00);
 }
 }
}
<divclass="seckill_coupon">
<spanclass="seckill_coupon_item">
<divclass="seckill_coupon_item_top">

</div>
<divclass="seckill_coupon_item_bottom">

</div>
</span>
</div>

测试结果:

设备 浏览器 支持度 截图
iPhone 6/6+
(iOS 9/10)
Safari/WeChat 支持 CSS3 Mask 安利报告
魅蓝
(Android 4.4.4)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
魅蓝
(Android 4.4.4)
原生浏览器 支持 CSS3 Mask 安利报告
红米
(Android 4.4.4)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
红米
(Android 4.4.4)
原生浏览器 支持 CSS3 Mask 安利报告
三星GT-I9300
(Android 4.3)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
三星GT-I9300
(Android 4.3)
原生浏览器 不友好 CSS3 Mask 安利报告
荣耀3c
(Android 4.2.2)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
荣耀3c
(Android 4.2.2)
原生浏览器 不友好 CSS3 Mask 安利报告
Lumia RM-1090
(windows mobile)
ie 不支持 CSS3 Mask 安利报告

测试解读:

虽然测试的机型不多,但仍然可以看出 Android 4.3及以下版本原生浏览器对多蒙层的支持 不友好 ,windows mobile是 不支持 ,而使用 X5 内核的 WeChat 6.3.25对多蒙层的支持度是良好的。

取消多蒙层 视作 多蒙层的降级以处理 不友好 的机型:

CSS3 Mask 安利报告 – 降级 -> CSS3 Mask 安利报告

通过 @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,05px, (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:

CSS3 Mask 安利报告 (未使用 @supports 降级)

CSS3 Mask 安利报告 (使用 @supports 降级)

测试结论

  1. 微信手Q平台,使用多蒙层是友好的
  2. 非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 2012mask-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 2014mask-box

W3C Last Call Working Draft, 22 May 2014mask-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:94491fill;
-webkit-mask-box-image-width:5px23px5px5px;
-webkit-mask-box-image-repeat: stretch stretch;

// 兼容未来
mask-border-source: url(images/seckill_coupon_half.png?__inline);
mask-border-slice:94491fill;
mask-border-width:5px23px5px5px;
mask-border-repeat: stretch stretch;

如果是使用 sassless 的同学,推荐安装 autoprefixer 插件。 autoprefixer 可以为使用者解决 css 兼容写法的烦恼,有了它,mask-border 可以直接使用 兼容未来 写法:

// 在安装了 autoprefixer 后
mask-border-source: url(images/seckill_coupon_half.png?__inline);
mask-border-slice:94491fill;
mask-border-width:5px23px5px5px;
mask-border-repeat: stretch stretch;

4.3 Mask-border 实例

上节多蒙层的例子使用 mask-border 来实现会更合适:

目标图形:

CSS3 Mask 安利报告

素材:

CSS3 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:0auto;
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:94491fill;
mask-border-width:5px23px5px5px;
 &_top {
background:#f2f7f7linear-gradient(to bottom,#fafcfc,#f2f7f7);
border-radius:3px3px00;
height: (70px/2);
width:100%;
 }
 &_bottom {
width:100%;
height: (50px/2);
border-radius:003px3px;
background-image: linear-gradient(to bottom,#ff9600,#ff7c00);
 }
 }
}
<divclass="seckill_coupon">
<spanclass="seckill_coupon_item">
<divclass="seckill_coupon_item_top">

</div>
<divclass="seckill_coupon_item_bottom">

</div>
</span>
</div>

以下是测试DEMO:

CSS3 Mask 安利报告

测试结果:

设备 浏览器 支持度 截图
iPhone 6/6+
(iOS 9/10)
Safari/WeChat 支持 CSS3 Mask 安利报告
魅蓝
(Android 4.4.4)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
魅蓝
(Android 4.4.4)
原生浏览器 支持 CSS3 Mask 安利报告
红米
(Android 4.4.4)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
红米
(Android 4.4.4)
原生浏览器 支持 CSS3 Mask 安利报告
三星GT-I9300
(Android 4.3)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
三星GT-I9300
(Android 4.3)
原生浏览器 支持 CSS3 Mask 安利报告
荣耀3c
(Android 4.2.2)
WeChat 6.3.25 支持 CSS3 Mask 安利报告
荣耀3c
(Android 4.2.2)
原生浏览器 支持 CSS3 Mask 安利报告
Lumia RM-1090
(windows mobile)
ie 不支持 CSS3 Mask 安利报告

测试结论

mask-border 在移动端的兼容性很好,推荐使用。

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址