css中-webkit-box-reflect属性简介及元素镜像倒影实现

 更新时间:2016年9月14日 14:19  点击:1907
-webkit-box-reflect是css3中的一个属性了,在这里我们一起来看一篇关于css中-webkit-box-reflect属性简介及元素镜像倒影实现例子。


一、从前有只鸭子
从前有只鸭子,长得不是一般的丑:

梁朝伟 我是一只鸭子

于是,鸭子一直很自卑,从来不敢照镜子,也不敢下河游泳。别的鸭子很喜欢下河游泳,因为可以一边玩耍,一边上WC,让吃进去的东西舒舒服服从后面出来;而这只鸭子一旦下河,吃进去的东西只会是从前面出来,因为总会不经意看到自己的脸。

就这样很过去了很多很多年,世事变化无常,当年会说话住山洞被鸭子调戏的猩猩逆袭现在住进了动物界的五星级宾馆——上海野生动物园;而鸭子自己,历经岁月的沧桑,容貌也发生了巨大的变化:

梁朝伟 很帅的鸭子

然而,鸭子却不知道这一切,因为它自卑不敢照镜子不敢游泳,所以它并不知道自己现在的容貌是什么样子,直到2016年8月中旬,鸭子偶然间遇到了一件宝物,这才突然发现自己现在™长得比梁朝伟还帅。

咦,既不是镜子,也不是水流,那是什么东西让鸭子知道了自己的真面目呢?

好,欢迎大家收看本期的走进前端:鸭子真面目毕露之宝物——box-reflect属性!

二、CSS宝物之盒倒影属性-webkit-box-reflect
当时的情形是这样的:鸭子有点感冒,痰有些多,于是决定趁机休个假打飞的去伦敦喂鸽子散个心,在机场候机的时候,旁边有个黑衣人模样的人正在用5K屏幕水果笔记本看电影《东成西就》,鸭子就侧过去一起看了。当电影放到“香肠嘴”那里的时候,鸭子居然狂笑了起来!

梁朝伟香肠嘴

居然,没错,是“居然”!你可知道,鸭子这数百年来几乎就没笑过,即使这几个世纪见过无数搞笑的场景,但是,一直把笑压抑在自己心中。但是,或许是因为这“香肠嘴”有一种前世熟悉的感觉,让自己一下子没忍住,连同之前数百年压抑的笑一下子喷薄了出来,“哈……哈……”

哈哈

然而,当鸭子一瞬间意识到自己笑出声的时候,容不得自己思考,似乎发现自己犯了天大错误一样,使尽全力收住自己的笑气。但是,这百年积攒的笑气能量之强,岂是想收住就能收住了。一瞬间,笑气内涌,胸腔顿时涨裂之感,无法呼吸。鸭子实在无法忍受,翻涌的能量化作利剑一般,伴随一声巨咳从口中释放出来。

这一切来得是如此的突然如此的猝不及防,虽有些失色,有些狼狈,但还不至于造成太大的干扰,毕竟就2个笑声,1个咳嗽声而已。直到鸭子长吁一口气,继续看黑衣男笔记本的时候……鸭子发现5K屏幕上多了形状像“八”的粘性液体组成的图案。这一瞬间,世界似乎停止了运转,鸭子真希望现在有条河可以让自己钻进去~~

但是,黑衣男似乎很镇定,只见他一键关机,然后,顺势从肚子前的口袋里拿出了写着-webkit-box-reflect字样的魔法布,对着5K屏幕就这么一抹,卧槽,奇迹发生了,没有任何接触,屏幕体贴变得干干净净,不仅如此,屏幕变得剔透异常,把周围景物反射的清清楚楚。

此时,鸭子突然从屏幕中看到了一个大帅哥,“咦,此人长得跟我很像嘛……” (目标浏览器才有倒影,IE和FireFox留白无倒影)

 

后面的故事大家应该就知道了,从此,鸭子开始自信起来,笑容也多了起来,这就是“丑小鸭变成白天鹅”的故事。

上面让鸭子看到自己面容倒影的宝物就是CSS届的-webkit-box-reflect,上面施展的魔法技能是:

-webkit-box-reflect: below;
当然,既然是宝物,技能不可能只有一件,速速全部拿来开光。

语法如下:

-webkit-box-reflect: [ above | below | right | left ]? ? ?
上面语法中,[]|?都是正则表达式中的通用表达含义,例如?表示0个或1个。|表示或者的意思。具体来说-webkit-box-reflect最多可以由3部分组成,分别如下:

方位
可以是下面4个值中的1个,above,below,left,right,分别表示上下左右。如果不是使用类似inherit等全局关键字,则此方位值是不能缺省的。
偏移大小
倒影和原始元素偏移距离。可以是数值,也可以是百分比值。如果是百分比值,则百分比大小是相对于元素自身尺寸计算的。和transform中translate的百分比计算是一致的。
遮罩图片
对元素倒影的遮罩控制。语法类似于background-image。
因此,我们可以有如下的一些书写:

-webkit-box-reflect: below;

-webkit-box-reflect: right;

-webkit-box-reflect: right 10px;

-webkit-box-reflect: below 0 linear-gradient(transparent, white);

-webkit-box-reflect: below 0 url(shuai2.png);
等。然后,对应的效果如下:

您可以狠狠地点击这里:-webkit-box-reflect各个属性值效果演示demo

如果您使用的是Chrome或Safari浏览器,或者使用的是手机设备浏览,则应该会看到类似下面截图的效果:
倒影效果截图

分别对应上面书写的效果。然而,还有很多信息是demo里面体现不出来需要额外说明的。

其他说明

倒影不占据尺寸空间,是和outline, box-shadow一样的那种真正意义上的不占据空间尺寸。所以,demo使用了padding值撑开间距,免得几张鸭子图片重叠在一起;
上面提到了,倒影偏移值支持百分比,且是根据元素自身尺寸计算的。但还有一点需要补充,就是,尺寸计算的方位是根据你的倒影方向自动识别的。比说说,你的倒影方向是below或above,则偏移百分比是根据原始元素的高度想计算的,如你的倒影方向是left或right,则根据元素的宽度来计算;
遮罩图片可以使用CSS3渐变。并且,这里的渐变语法和CSS3 background-image的语法几乎是一模一样的。注意这里的措辞“几乎”,说明还是有不同之处的,不同支持就是-webkit-box-reflect的遮罩图片不支持多图(对于background的多背景),只能是一张图。其他的语法就是一模一样的。包括不仅支持线性渐变(linear-gradient),还支持径向渐变(radial-gradient),支持to top或to bottom新语法,支持stop断点,例如:
-webkit-box-reflect: below 0 linear-gradient(transparent, white 50%, white);
使用遮罩图片的时候,倒影的偏移值是不能缺省的。如果没有偏移,请使用0占位,这也是为何示意代码中有个0的原因;
遮罩的最终效果与颜色无关,也就是你使用linear-gradient(transparent, white)和linear-gradient(transparent, black)的效果是一模一样的,关键在于是否透明以及透明度是多少。实色遮罩的结果就是透明,透明遮罩的结果就是暴露原始色值。
遮罩图片也可以直接是图片,语法同background-image。但是有个需要注意的是,当图片应用于倒影遮罩的时候,这个图片自身也会被(因倒影)而翻转。比方说上面demo最后一个例子,遮罩出了一个“帅”字,而这个原始的“帅”文字图片是这样的:
“帅”字
大家发现没,是倒着的。这样,倒影下来,我们就可以在倒影上看到正过来的“帅”效果了。

倒影效果具有实时渲染特性。也就是,如果我们突然把鸭子恢复到当年“丑小鸭”的状态,则,鸭子一定会想起不堪回事的往事。
丑小鸭倒影
于是,我们可以利用这一特性,实现一些很酷的动效。对吧,就那种……上面动下面也跟着一起动的那种……你应该懂的~~

三、-webkit-box-reflect兼容性
-webkit-box-reflect说到现在,我几乎就米有把-webkit-私有前缀去掉,因为,盒倒影属性box-reflect本身就是webkit私有的一个特性,并且支持已经有很多很多年了,所以,只要浏览器是-webkit-内核,均支持该属性。

包括Chrome/Safari/Opera以及移动端浏览器(from caniuse):
倒影兼容性表

所以,我们可以在内部项目,或者在移动端项目中放心大胆使用该CSS属性。

那如果我们需要在传统PC项目上也能实现投影效果,该怎么办呢?其实是可以曲线救国的。

四、-moz-element()让FireFox浏览器也支持元素投影
首先,我们看看FireFox也没有什么方法可以实现元素投影效果。

有,试试element()函数,关于element()函数,我在2011的时候就介绍过,“CSS3 background扩展属性element简介”, 可以让一个元素作为背景使用,语法很简单:

 background: element(#id)
只要#id对应的元素不是<img>元素①,也是具有实时跟踪渲染特性的。

//zxx: 不知从哪个版本开始,FireFox不支持图片的跟踪渲染了~~

如果是FireFox浏览器,您可以狠狠地点击这里:利用-moz-element()实现倒影demo

进入页面扑面而来的是这样的效果:
FireFox浏览器下的倒影效果

我们点击demo页面下面的按钮,让原图旋转起来,大家可以发现,倒影图片也旋转起来了。

旋转跟随截图

然而,和真正的倒影效果相比,还是有很多问题的。

局限

不支持遮罩。demo所见的“倒影”实际是覆盖了一层白色渐变模拟的。
占据空间。展示的倒影是不占据任何尺寸位置的。但是,如果background模拟,就需要设定一个尺寸。且背景图片是无法超出元素的,因此(如上图所示),倒影可能会显示不全。
倒影的位置是死的。真实的倒影旋转应该是下图这样,而不是上图那样:
真实的倒影和旋转的位置关系
渲染性能很差。FireFox浏览器下,原图在360度旋转,但是,“倒影”元素的旋转取像是吃了“含笑半步癫”,一癫一癫、一顿一顿的,一股IE6的春风扑面而来。
所以,总结下来,-moz-element()只适合模拟静态倒影效果。

五、让IE浏览器也支持元素投影
现在,webkit/moz两派都登场了,那IE浏览器怎么办呢?有没有什么私有的倒影属性之类的。

在我目前所掌握的知识范畴里,没有。

但是,要想实现也是可以的。

可以使用现代web技术,SVG和canvas都是可以的。

如果使用这些技术,自然,Chrome和FireFox浏览器也是支持的。也就是,如果你想在全兼容的页面实现倒影效果,可以试试SVG或canvas,但是,有局限,只适用于图片,或文本,如果是复杂的DOM结构,理论上可以实现,但实际成本相当感人,是不划算滴。

所以,这里展示下,如何使用SVG和canvas实现图片倒影效果。

1. SVG实现倒影
SVG中有真正意义的遮罩,且可以使用fill属性吧图片作为底纹填充给多个元素,理论上就实现了原图和倒影的联动效果。

还是使用鸭子图片做示意,代码如下:

<svg width="150" height="352">
  <defs>
      <linearGradient id="gradient" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0%"   stop-color="#fff" stop-opacity="0"/>
      <stop offset="100%" stop-color="#fff" stop-opacity="1"/>
    </linearGradient>
    <mask id="mask">
      <rect x="0" y="176" width="150" height="177" fill="url(#gradient)"  />
    </mask>
    <pattern id="reflect" patternUnits="userSpaceOnUse" width="150" height="176">
      <image xlink:href="chaowei.jpg" width="150" height="176" />
    </pattern>
  </defs>
  <!-- 原图 -->
  <rect x="0" y="0" width="150" height="176" fill="url(#reflect)"></rect>
  <!-- 倒影图 -->
  <rect x="0" y="176" width="150" height="176" fill="url(#reflect)" mask="url(#mask)" transform="translate(75 264) scale(1, -1) translate(-75 -264)"></rect>
</svg>
您可以狠狠地点击这里:SVG实现倒影效果演示demo

效果如下:

2. canvas实现倒影
关于canvas实现倒影,以前曾分享过一个JS插件,具体参见:“reflection.js-实现图片倒影效果js插件”,这篇文章是相当元老的一篇文章,发表于09年的8月份。

reflection.js是一个很简单的JS文件,很小,您可以点击这里下载之~

由于此JS文件比较老,有些地方有些out,比方说IE9支持canvas,但是,实际却是有filter去实现,是有问题的,如下处修改:

// 第65行
if (document.all && !window.opera) {

if (![].map) {
reflection.js会自动对含有reflect类名的图片进行倒影处理。

您可以狠狠地点击这里:鸭子变帅后canvas倒影效果demo

 

使用很简单:

<img src="chaowei.jpg" class="reflect">

<script src="reflection.js"></script>
<script>
// 全身倒影
Reflection.defaultHeight = 1;
// 倒影透明度变化从0到1
Reflection.defaultOpacity = 1;
</script>
此实现同样有一些局限,例如:不支持动态变化,投影占据空间尺寸等。

六、让IE7/IE8也支持元素倒影
虽然SVG和canvas可以让IE也能实现图片的静态投影效果,但是,对于IE7,IE8浏览器怎么办?这些都不支持的。

如果非要让IE7/IE8也能实现倒影效果,也是可以的,需要使用IE的私有滤镜来模拟。

一个是flipV/flipH翻转,还有一个就是渐变滤镜(如透明到白色)覆盖图片。

关于IE的水平或垂直翻转,之前有文章介绍过:“CSS垂直翻转/水平翻转提高web页面资源重用性”。

/*水平翻转*/
.flipx {
    transform:scaleX(-1);
    /*IE*/
    filter:FlipH;
}

/*垂直翻转*/
.flipy {
    transform:scaleY(-1);
    /*IE*/
    filter:FlipV;
}
关于IE的渐变滤镜,之前也有文章介绍过:“CSS实现兼容性的渐变背景(gradient)效果”。

filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=red,endcolorstr=blue,gradientType=1);
现在,IE7,IE8浏览器的份额已经比较低了,为了这些过时的浏览器去折腾一些比较酷的视觉效果,我觉得是非常不划算的事情,个人建议是,直接就不要倒影什么的,满足基本功能是第一位。因为,人力成本也是成本,而且这些技术都是要被淘汰的,花时间掌握日后的收益怕是有些低。

所以,这里就不专门整demo展示IE7/IE8下图片倒影效果的实现了。

 

七、结束语
感谢-webkit-box-reflect,让鸭子找回了自信,这不,喂完鸽子回来,敢和空姐合影了。

梁朝伟喂完鸽子回来

这个故事说明了什么?

很显然,学好CSS,丑小鸭也能变成白天鹅,娶空姐,走上人生巅峰……

[!--infotagslink--]

相关文章

  • 浅谈C# 字段和属性

    这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
  • php语言实现redis的客户端

    php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。 为了更好的了解redis协议,我们用php来实现...2016-11-25
  • jQuery+jRange实现滑动选取数值范围特效

    有时我们在页面上需要选择数值范围,如购物时选取价格区间,购买主机时自主选取CPU,内存大小配置等,使用直观的滑块条直接选取想要的数值大小即可,无需手动输入数值,操作简单又方便。HTML首先载入jQuery库文件以及jRange相关...2015-03-15
  • JS实现的简洁纵向滑动菜单(滑动门)效果

    本文实例讲述了JS实现的简洁纵向滑动菜单(滑动门)效果。分享给大家供大家参考,具体如下:这是一款纵向布局的CSS+JavaScript滑动门代码,相当简洁的手法来实现,如果对颜色不满意,你可以试着自己修改CSS代码,这个滑动门将每一...2015-10-21
  • js修改input的type属性问题探讨

    js修改input的type属性有些限制。当input元素还未插入文档流之前,是可以修改它的值的,在ie和ff下都没问题。但如果input已经存在于页面,其type属性在ie下就成了只读属性了,不可以修改。...2013-10-19
  • jQuery+slidereveal实现的面板滑动侧边展出效果

    我们借助一款jQuery插件:slidereveal.js,可以使用它控制面板左右侧滑出与隐藏等效果,项目地址:https://github.com/nnattawat/slideReveal。如何使用首先在页面中加载jquery库文件和slidereveal.js插件。复制代码 代码如...2015-03-15
  • PHP+jQuery翻板抽奖功能实现

    翻板抽奖的实现流程:前端页面提供6个方块,用数字1-6依次表示6个不同的方块,当抽奖者点击6个方块中的某一块时,方块翻转到背面,显示抽奖中奖信息。看似简单的一个操作过程,却包含着WEB技术的很多知识面,所以本文的读者应该熟...2015-10-21
  • SQLMAP结合Meterpreter实现注入渗透返回shell

    sqlmap 是一个自动SQL 射入工具。它是可胜任执行一个广泛的数据库管理系统后端指印, 检索遥远的DBMS 数据库等,下面我们来看一个学习例子。 自己搭建一个PHP+MYSQ...2016-11-25
  • Vue之计算属性详解

    这篇文章主要为大家介绍了Vue的计算属性,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...2021-11-16
  • PHP实现今天是星期几的几种写法

    复制代码 代码如下: // 第一种写法 $da = date("w"); if( $da == "1" ){ echo "今天是星期一"; }else if( $da == "2" ){ echo "今天是星期二"; }else if( $da == "3" ){ echo "今天是星期三"; }else if( $da == "4"...2013-10-04
  • 原生js实现fadein 和 fadeout淡入淡出效果

    js里面设置DOM节点透明度的函数属性:filter= "alpha(opacity=" + value+ ")"(兼容ie)和opacity=value/100(兼容FF和GG)。 先来看看设置透明度的兼容性代码: 复制代码 代码如下: function setOpacity(ele, opacity) { if (...2014-06-07
  • C# Dynamic关键字之:调用属性、方法、字段的实现方法

    本篇文章是对C#中调用属性、方法、字段的实现方法进行了详细的分析介绍,需要的朋友参考下...2020-06-25
  • 详解jquery方法属性

    这篇文章主要介绍了jquery的方法属性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-11-10
  • Android中用HttpClient实现Http请求通信

    本文我们需要解决的问题是如何实现Http请求来实现通信,解决Android 2.3 版本以后无法使用Http请求问题,下面请看正文。 Android开发中使用HttpClient来开发Http程序...2016-09-20
  • JavaScript中的Reflect对象详解(ES6新特性)

    这篇文章主要介绍了JavaScript中的Reflect对象(ES6新特性)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2016-07-29
  • 关于vue属性使用和不使用冒号的区别说明

    这篇文章主要介绍了关于vue属性使用和不使用冒号的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-22
  • C# 列表List的常用属性和方法介绍

    这篇文章主要介绍了C# 列表List的常用属性和方法介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • mysql存储过程实现split示例

    复制代码 代码如下:call PROCEDURE_split('分享,代码,片段',',');select * from splittable;复制代码 代码如下:drop PROCEDURE if exists procedure_split;CREATE PROCEDURE `procedure_split`( inputstring varc...2014-05-31
  • 在Vue中获取自定义属性方法:data-id的实例

    这篇文章主要介绍了在Vue中获取自定义属性方法:data-id的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-09
  • C#类中属性与成员变量的使用小结

    本篇文章主要是对C#类中属性与成员变量的使用进行了总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助...2020-06-25