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的统计:

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源码:

1// 生成 黑、红、黄、蓝四个 icon。.icon { 2 display: inline-block; 3 width: 30px; 4 height: 30px; 5 background-color: black; // 控制图标的颜色 6 -webkit-mask: url(images/icon.png) 0 0 no-repeat; 7 -webkit-mask-size: 100% 100%; 8 &.red { 9 background-color: red; 10 } 11 &.yellow { 12 background-color: yellow; 13 } 14 &.blue { 15 background-color: blue; 16 }}

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。

1p { 2 margin: 0; 3 padding: 10px; 4 color: #000; 5 font-size: 14px;}.icon { 6 display: inline-block; 7 width: 15px; 8 height: 15px; 9 background-color: currentColor; // 控制图标的颜色 - 默认当前color值 10 -webkit-mask: url(images/icon.png) 0 0 no-repeat; 11 -webkit-mask-size: 100% 100%;}.red { 12 color: red;}.yellow { 13 color: yellow;}.blue { 14 color: blue;} 15 16<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)

测试代码如下:

1.seckill_coupon { 2 width: (718px / 2); 3 height: auto; 4 margin: 0 auto; 5 font-size: 0; 6 font-family: Helvetica; 7 &_item { 8 width: (226px / 2); 9 height: ( 120px / 2 ); 10 display: inline-block; 11 -webkit-mask-image: url(images/seckill_coupon_ellipsis.png?__inline), url(images/seckill_coupon_100px.png?__inline), url(images/seckill_coupon_ellipsis.png?__inline); 12 -webkit-mask-position: (190px / 2) -5px, 0 5px, (190px / 2) 55px; 13 -webkit-mask-repeat: repeat-x, no-repeat, repeat-x; 14 -webkit-mask-size: (750px / 2) auto, (750px / 2) auto, (750px / 2) auto; 15 &_top { 16 background: #f2f7f7 linear-gradient(to bottom, #fafcfc, #f2f7f7); 17 border-radius: 3px 3px 0 0; 18 height: ( 70px / 2 ); 19 width: 100%; 20 } 21 &_bottom { 22 width: 100%; 23 height: ( 50px / 2 ); 24 border-radius: 0 0 3px 3px; 25 background-image: linear-gradient(to bottom, #ff9600, #ff7c00); 26 } 27 }} 28 29<div class="seckill_coupon"> 30 <span class="seckill_coupon_item"> 31 <div class="seckill_coupon_item_top"> 32 </div> 33 <div class="seckill_coupon_item_bottom"> 34 </div> 35 </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 来做降级处理:

1@supports (-webkit-mask-repeat: repeat) { 2 -webkit-mask-image: url(images/seckill_coupon_ellipsis.png?__inline), url(images/seckill_coupon_100px.png?__inline), url(images/seckill_coupon_ellipsis.png?__inline); 3 -webkit-mask-position: (190px / 2) -5px, 0 5px, (190px / 2) 55px; 4 -webkit-mask-repeat: repeat-x, no-repeat, repeat-x; 5 -webkit-mask-size: (750px / 2) auto, (750px / 2) auto, (750px / 2) auto;}

不过,使用 @supports 后,(荣耀3c与三星 GT I9300的)X5内核也被降级,这并不是最理想的结果。以下是测试DEMO:


(未使用 @supports 降级)


(使用 @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 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;

如果是使用 sassless 的同学,推荐安装 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)

测试代码:

1.seckill_coupon { 2 width: (718px / 2); 3 height: auto; 4 margin: 0 auto; 5 font-size: 0; 6 font-family: Helvetica; 7 &_item { 8 width: (226px / 2); 9 height: ( 120px / 2 ); 10 display: inline-block; 11 mask-border-source: url(images/seckill_coupon_half.png?__inline); 12 mask-border-slice: 9 44 9 1 fill; 13 mask-border-width: 5px 23px 5px 5px; 14 &_top { 15 background: #f2f7f7 linear-gradient(to bottom, #fafcfc, #f2f7f7); 16 border-radius: 3px 3px 0 0; 17 height: ( 70px / 2 ); 18 width: 100%; 19 } 20 &_bottom { 21 width: 100%; 22 height: ( 50px / 2 ); 23 border-radius: 0 0 3px 3px; 24 background-image: linear-gradient(to bottom, #ff9600, #ff7c00); 25 } 26 }} 27 28<div class="seckill_coupon"> 29 <span class="seckill_coupon_item"> 30 <div class="seckill_coupon_item_top"> 31 32 </div> 33 <div class="seckill_coupon_item_bottom"> 34 35 </div> 36 </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源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )