CSS3 border-image详解、应用及jQuery插件

一、border-image的兼容性

border-image可以说是CSS3中的一员大将,将来一定会大放光彩,其应用潜力真的是非常的惊人。可惜目前支持的浏览器有限,仅Firefox3.5,chrome浏览器,Safari3+支持border-image。所以,就本文而言,IE浏览器可以回家休息了,Firefox3及其以下以及Opera浏览器也可以休息去看《阿凡达》了。所以,本文提供的一些demo页面,要在Firefox3.5+,chrome或Safari3+浏览器下才可以看到效果。
CSS3 中文手册上border-image兼容性缩略图

更新于2016-06-14
现在IE11+,FireFox以及Chrome浏览器均已支持border-image,并且目前也就Android4.3及其以下版本需要-webkit-私有前缀,可以说border-image的时代即将到来。

//zxx: 没想到这一晃一等就是6年!

二、熟悉border-image的一些特性

我们可能对于CSS2中的background属性比较熟悉,例如:background:url(xx.jpg) 27px no-repeat;
指代的是图片(url(xx.jpg)),位置(27px),重复性(no-repeat)。

border-image于此类似,border-image包括图片,剪裁位置(与background位置一样,也是数值,也支持百分值),重复性。例如:border-image:url(border.png) 27 repeat;,指的就是图片(url(border.png)),剪裁位置(27),重复方式(repeat)。试着对比background,这有助于border-image属性的记忆。

具体描述border-image的参数
border-image的参数就是上面提到的三个:图片,剪裁位置,重复性。
1、图片(border-image-source)
与CSS2中background-image属性一样,border-image的背景图使用url()调用,图片可以是相对路径或是绝对路径,也可以不使用图片,即border-image:none;

2、图片剪裁位置(border-image-slice)
此参数特点比较鲜明:
1、没有单位,专指像素。这类似于flash的as脚本,舞台高宽,影片剪辑大小,位移直接就是一个数值,没有单位,因为默认单位就是像素(px)了。例如:border-image:url(border.png) 27 repeat;这里的27专指27像素。

2、支持百分比值,百分比值大小事相对于边框图片而言,假设边框图片大小为400px*300px,则20%的实际效果就是剪裁了图片的60px 80px 60px 80px的四边大小。

3、剪裁特性。如果您对CSS中clip属性(clip:rect(auto, auto, auto, auto))比较了解,则这里理解就会轻松些。clip可以说是CSS中一个明目张胆的剪裁属性,而此处的属性虽然表意上不是剪裁,但是在border-image效果的实现上来说,就好像是个剪裁工具,把边框图片四分五裂,再重新安置,变形。其有1~4个参数,其方位规则符合CSS普遍的方位规则(与margin,padding等或border-width一致),上右下左顺时针,再赋予剪裁的含义,举个简单的例子,前面提到,支持百分比宽度,所以这里“30% 35% 40% 30%的”示意可以用下图表示:

剪裁示意

看图说话就是,离图片上部30%的地方剪裁一下,在右边35%的地方剪裁一下,在离底部40%的地方裁剪一下,在距左边30%的地方也剪裁一下。于是总共对图片进行了“四刀切”,形成了九个分离的区域,这就是九宫格,这是下面深入讲解border-image的基础。

3、重复性(border-image-repeat)
这里的重复性有别于background的背景重复,差别较大。background图片就是重复,不重复,水平重复,垂直重复,总之就是围绕repeat(重复)这个词打转,一家独大。而对于border-image,可谓是三足鼎立,repeat(重复)只是其中之一,其余两个是round(平铺)和stretch(拉伸)。其中,stretch是默认值。

参数0~2个,0则使用默认值 – stretch,例如:border-image:url(border.png) 30% 40%;就等同于border-image:url(border.png) 30% 40% stretch stretch;;1则表示水平方向及垂直方向均使用此参数;2个参数的话则第一个参数表水平方向,第二个参数表示垂直方向。例如:border-image:url(border.png) 30% 40%;就等同于border-image:url(border.png) 30% 40% round repeat;表示水平方向round(平铺),垂直方向repeat(重复),至于何为平铺何为重复下面会深入讲解。

三、深入理解border-image的宽度和展示方式

分开理解border-image的宽度或是展示方式其实不太难的,关键是这两者结合使用时候的含义,需要花一定的功夫的理解。

帮助理解的九宫格模型
何为九宫格?为什么我们需要九宫格帮助理解?
简单的数字九宫格
“九宫格”是我国书法史上临帖写仿的一种界格,又叫“九方格”,即在纸上画出若干大方框,再于每个方框内分出九个小方格,以便对照法帖范字的笔画部位进行练字。在本文,“九宫格”就专指由九个方格形成的矩形布局,例如左图就是一个很简单的数字九宫格。

border-image的数值参数其实是用来剪裁边框图片的,正好“哗哗四刀”切出了个九宫格的模型,所以,有意或无意,巧合还是必然,我们需要用到九宫格模型帮助我们理解border-image的绘制原理。下面这张图是本文非常重要的基本的示意图,因为这是张具有代表性的九宫格图案(27*3)*(27*3)。
九宫格代表图gif演示<————————>九宫格代表图gif演示

这张图能够帮助我们更好的理解border-image的剪裁及绘制的原理。

边框将border-image分成了九部分:border-top-image , border-right-image , border-bottom-image , border-left-image, border-top-left-image , border-top-right-image , border-bottom-left-image , border-bottom-right-image以及中间的内容区域。假设现在边框的宽度是27像素,则上面所说的九部分正如下图所表示的(放大400%):
边框分割与九宫格

左图中,橙红色的四个边角的菱形区域称为“角边框图片”,在border-image中,角边框图片是没有任何展示效果的,不会平铺,不会重复,也不会拉伸,有点类似于视觉中盲点的意思。

而对边的四个橙黄色区域属于展示效果的作用区(也是边框宽度计算剩余区),上下区域即border-top-image和border-bottom-image区域受到展示效果属性的第一个参数——水平方向效果影响:如果为repeat,则此区域图片会水平重复,如果是round,则此框框内的图片会水平平铺,如果是stretch,则此矩形域中的图片就会被水平拉伸。(下部分的实例会做具体演示)左右区域只有垂直方向上的效果,与上下区域效果对应,不多说。

中间的区域(左图的空白格)受到全部参数的作用,在水平和垂直两个维度上都有展示效果(平铺、拉伸等)。

这里,插一点内容,讲一下round(平铺),repeat(重复),stretch(拉伸)所具体指代的效果。这三个特性其实大家应该都比较熟悉。看下图:
桌面背景图的显示方式

在windows系统桌面壁纸显示方式选项中就有“拉伸”和“平铺”,这两个效果与border中“拉伸”和“平铺”效果一致。只是可能在理解“平铺”和“重复”的区别上有点丈二的和尚——摸不着头脑。记住这么一点:平铺可能会改变了原图片显示的大小,重复不改变图片显示的大小。

这么比方吧,您从万科地产买了个99.5m*99.5m的毛坯房,地面要贴瓷砖,都是1m*1m的正方形瓷砖。如果是“平铺”,对不起,这1m边长的瓷砖不行,要处理!怎么处理法?很简单,每个瓷砖压成0.995m*0.995m的,这样就可以了,所以,平铺就是以完整的单元铺满整个区域。如果是重复,就直接把这1m*1m的瓷砖从一个角落一个一个的放置,放到头放不下了怎么办?直接把瓷砖从中间“咔”掉,于是最后会在房子的边角看到很多半截的瓷砖。下面就是一个个的实例演示了,您可以通过下面的实例效果中加深理解。

帮助理解的一些实例
下面的实例代码对应的demo页面要在Firefox3.5、chrome或Safari3+浏览器下才可以看到效果。所使用的背景图片就是前面提到的九宫格代表图(8菱形 – 81px*81px),名称为border.png。

1、27像素剪裁宽高(1/3边框图片宽高)在1em边框宽度下的默认显示
CSS代码:

.border_image{
    width:400px;
    height:100px;
    border:1em double orange;
    border-image:url(../image/border.png) 27;     
}

结果:
border-image默认显示

您可以狠狠地点击这里:实例demo1

效果分析:
这里没有显示方式的参数,正如上面所说的,0参数即使用默认的stretch拉伸,所以从图上可以看到四个对边的拉伸效果。上面还提到,四个对角是不受重复方式影响,该什么样子还是什么样子,无拉伸平铺,本面目示人。见下图的标注(放大200%)。
拉伸的标注

这个九宫格各区域展示方式的标注图在border-image中是通用的,无论border-image的代码如何改变,其显示效果的原理核心就是左边这张九宫标注图,亘古不变的是四个边角,这四个边角就是四条边框的重叠区域,不会有拉伸或是重复的展现效果。有变化的就是四边区域和中心区域,这几个区域中的水平和垂直属性也是稳如泰山,屹立不变的,改变的就只是“拉伸”而已,变成重复啦或是平铺。

由于其通用性,所以此显示原理标注图在下面就不一一展示了,您找到对应的位置,修改“拉伸”为“平铺”或“重复”即可,其他都不用改变。

2、27像素剪裁在1em边框宽度下round(平铺)显示效果
CSS代码:

.border_image{
    width:400px;
    height:100px;
    border:1em double orange;
    border-image:url(../image/border.png) 27 round; 
}

结果:
round效果图

您可以狠狠地点击这里:实例demo2

3、27像素剪裁在1em边框宽度下repeat(重复)效果
CSS代码:

.border_image{
    width:400px;
    height:100px; 
    border:1em double orange;
    border-image:url(../image/border.png) 27 repeat;
}

结果:
repeat效果图

您可以狠狠地点击这里:实例demo3

上图我圈了四个边角,不难发现,这一个边角处的菱形都是被截掉的。这就是repeat的效果,还记得上面的毛坯房的例子吗?round会压缩(或伸展)图片大小使其正好在区域内显示,而repeat是不管三七二十一直接重复的,而且是居中重复,repeat从中间开始(这是我的观察,可能不准确)。

这里还有一点需要注意:在webkit核心的浏览器下这个round属性和repeat属性似乎没有没有区分,显示的效果是一样的,所以您在chrome浏览器或是Safari浏览器下看demo2和demo3的效果可能是一样的。Firefox3.5下可以准确区分这两个参数。

4、上实例样式缩写
上面的实例还可以进一步缩写。CSS如下:

.border_image{
    width:400px;
    height:100px;
    border:double orange;
    border-image:url(../image/border.png) 27/1em repeat;
}

实现的效果是一样的。您可以狠狠地点击这里:实例demo4

border-image绘制原理简述
我是这样理解的:共存在两个九宫格,一个是边框图片,还有一个就是边框本身,九个方位关系一一对应。边框本身的特性让其变成了一个九宫格,四条边框交错,加上其围住的区域,正好形成一个九宫格。边框图片则是通过图片剪裁实现了九宫格。这是理解绘制原理的基础。

1、调用边框图片
border-image的url属性,通过相对或绝对路径链接图片。

2、边框图片的剪裁
border-image的数值参数剪裁边框图片,形成九宫格。

3、剪裁图片填充边框
边框图片被切割成9部分,以一一对应的关系放到div边框的九宫格中,然后再压缩(或拉伸)至边框(border-width或border-image-width)的宽度大小。

4、执行重复属性
被填充至边框九宫格四个角落的的边框图片是不执行重复属性的。上下的九宫格执行水平方向的重复属性(拉伸或平铺),左右的格子执行垂直方向的重复属性,而中间的那个格子则水平重复和垂直方向的重复都要执行。

5、完成绘制,实现效果

绘制原理动画示意,本flash动画以第一个demo效果做示例,请点击其中的“下一步”按钮,可看到一步一步的演示(如果flash无法显示,请点击这里直接观看):

四、border-image的一些应用

自适应的圆角效果
使用图片如下:
圆角素材图片

此图片的剪裁宽度为20像素,基本上就是此图的圆角大小。div的边框宽度为10像素,其CSS核心样式如下:

.border_image{
    border-image:url(../image/border.png) 20/10px; 
}

结果如下:
圆角效果

您可以狠狠地点击这里:圆角效果demo

多边框效果
使用图片如下:
多边框效果素材

圆角和边框大小都是20,就不上CSS代码了,大同小异。终效果如下图:
多边框效果图

您可以狠狠地点击这里:多边框效果demo

投影效果
使用素材图片如下:投影效果图片素材

剪裁宽度和边框宽度都是2 5 6 2,这里的投影我直接使用photoshop的投影样式生成的,发现用在边框投影上有一点点不足,需要手动调整,截取投影的四边,以及重复区域再拼合一下,您可以自己试试如果实现最佳的投影效果。

效果如下图:
照片的投影效果

您可以狠狠地点击这里:投影效果demo

选项卡
自适应选项卡,CSS2中实现自适应选项卡需要将背景图片制作的较长,而且需要两层标签,但是在CSS3中,图片要短,且一个标签就可以搞定。例如,这是淘宝新首页搜索选项卡的背景图片(已剪裁),,要是使用border-image,只要值么点图就可以了,实现选项卡效果需要的图片

边框图片剪裁大小和边框宽度都是5 5 0;底边为0,其余都是5像素,结果效果为:
选项卡实现的效果

您可以狠狠地点击这里:选项卡demo

其他
还有很多其他的应用,以前我们制作渐变背景,一张背景图很少可以重复使用,而有了border-image后就不会有这样的问题了,因为其可以拉伸。我们还可以利用border-image做高光按钮,做自适应的popup对话框,等等,太多了,就不一一举例了。

五、border-image效果的jQuery插件

正如开始所讲的,border-image仅Firefox3.5,chrome,Safari支持,IE这类浏览器不支持,但是并不代表他们无法实现类似的效果。例如利用canvas绘图,可以让Firefox2实现类似效果,IE下的VML语言也是支持矢量绘图,而这些就是此jQuery插件实现类似border-image效果的原理或称之为核心。

您可以狠狠地点击这里:jquery.borderImage.js(插件js)

使用方法
首先需要调用jQuery库,然后就是上面提供的js文件了。方法为borderImage,如下面的示例代码:

$('#element').borderImage('url("border.png") 30% 35% 40% 30%');

对此插件我个人评价不高,原因如下:
一是IE6及以上也可以实现类似canvas效果(需js插件支持),没有必要修改头部什么再使用VML绘图;
二是兼容性欠佳,IE6下无法实现高宽大于100像素的边框的拉伸;IE8下貌似也有点问题。
IE6下插件显示的糟糕效果

因而,我不具体说,一带而过。

您可以狠狠地点击这里:border-image效果jQuery插件demo

六、总结

从本文的篇幅可以看到border-image的潜力真是很惊人,我可以感觉到这将会是CSS3中的重磅武器之一。本文大部分的精力是在讲解border-image的原理,因为我非常看好border-image的应用前景,所以尽可能细致的讲清楚border-image各个属性的含义,让即使初学者也能较好的理解border-image的含义,本文列举的几个应用可以说只是border-image最基本的些应用。如果加上些创意的思考和天马行空的想象,真不知border-image可以创造出什么奇妙的事情来。

我开始深入学习CSS3方面的东西也只是最近开始,这东西,非要投入进入,你才会感受到这玩意真是酷,太不可思议了。我现在可以想象如果CSS3的世界到来,那时候,网页将会是多么精彩的一个世界。好了,就说这些,共同进步吧。

七、参考内容

1、百度百科,九宫格:http://baike.baidu.com/view/230179.htm?fr=ala0_1_1
2、W3C官方文档: CSS Backgrounds and Borders Module Level 3
3、CSS3中文手册
4、Meet a ninja living in browsers

如果您发现文章中有表述不准确或是有相关问题需要交流可以通过评论或是去这里进行提问交流。
原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=518

(完)

分享到:

标签: , , , , ,

赞助商推荐(我也要赞助)

想学到点真东西? ×
如果你有1~3年前端开发经验,不妨 ×
想要工资30K? ×


发表评论(目前50 条评论)

  1. violet说道:

    demo里自适应圆角效果和多边框效果在预览的时候没有展示出正确的效果,但是把代码复制到codepen里时,却是好好的。

  2. Mona-C说道:

    border-image对图片是否有要求呢?我试了几次都是实心边框。代码没有错。

  3. KAZUKI说道:

    太感谢了, 简单易懂, 单看 w3c 根本不明白, 不过好像漏了个 border-image-outset

  4. farceOrJoke说道:

    鑫神,圆角效果demo 效果没出来,貌似border 要在border-image 之前设置

  5. 前端小唐说道:

    border-image以前一直都是似懂非懂,大神一讲已然全明白!

  6. 123说道:

    希望能举一个不是刚好将菱形完整切下来的例子,并讲述一下在此情况下repeated与round的区别。

    • 小小苏说道:

      是的,同楼上,现在一直还是搞不清楚那4个值是怎么来的,这是个值是他们的宽高,还是什么,还是不是很明白,自己写 的时候要怎么量取呢

      • 墨玉说道:

        那四个值是图片边框向内的偏移量吧,比如值5,就是从图片的开始截取5个像素然后填充进边框内。四个值分别是从上右下左开始截取。

  7. qiujiao说道:

    我想请问,怎样让webkit浏览器能够实现平铺,现在在Safari上round和repeat效果一样,我想实现round效果,可是实现不了

  8. irislm说道:

    初次学习border-image,非常感谢楼主的分享,学到了更多!但是有一疑问,文中代码 border属性是否需要设置在border-image之前?楼主给的W3C参考内容上有这么一句话:must set border shorthand firse,otherwise it erases “border-image”. 不知是否是自己理解有误。

  9. abelard说道:

    高人啊!谢谢!

  10. 醍醐说道:

    楼主,你有很多个demo没生效,border-image移到border属性之后就可以了,目测被覆盖了。

  11. koalagis说道:

    好文,一直很好奇border-image到底是怎么处理的

  12. 海之梦说道:

    牛!谢谢分享

  13. ayqy说道:

    原来,5年前的zxx大大还不是话唠。
    看到这篇没多少废话的文章真是眼前一亮啊
    (言辞多有不敬,纯属玩笑,见谅)

  14. 燕君说道:

    大神好棒,每次查CSS的问题都查到你的博客……
    想问一下,border-image如果不用图片,用linear-gradient(to bottom,#ccc 20%,#6ef 50%),后面的剪裁宽度怎么设置?代表什么意思?

  15. 菜鸟说道说道:

    激动啊!看完了!很好理解!这个属性真的有用 在我的想像中 配合keyframes能大方光彩!!!谢谢博主

  16. lx说道:

    “中间的区域(左图的空白格)受到全部参数的作用,在水平和垂直两个维度上都有展示效果(平铺、拉伸等)。”
    这句我测试的貌似不对,中间的不管有没有图片,都不会显示。貌似被切除掉了

  17. tarol说道:

    这才是技术贴,非常精彩!

  18. huanhuan8808说道:

    你说的额很好,但是还没有看的很懂

  19. grass说道:

    “中间的区域(左图的空白格)受到全部参数的作用,在水平和垂直两个维度上都有展示效果(平铺、拉伸等)”

    这个好像不对啊,我的测试结果是,水平永远是stretch,垂直方向跟它设的参数有关

  20. Storm说道:

    楼主写的太棒了,我喜欢,深入浅出

  21. bigyang说道:

    楼主,FF15以后的版本,好像不支持border-image了
    在firebug里面查看,仍然可以识别-moz-boder-image和border-image,但是没有显示效果

  22. 安莫墨说道:

    楼主啊,按照九宫格的划分方法,为什么中间那个格子不重复了?就像“自适应的圆角效果”这个例子,中间是空白的。、。。

  23. Ava说道:

    我的firefox版本是最新的15.0.1,为什么我测试的时候不支持 -moz-border-image,谷歌是可以支持的,求解惑

  24. 十年灯说道:

    写的很详细,最近正在学习CSS3…感叹css3可以为我们节省多少图片哪。渐变,投影,半透明什么的毫无压力。

  25. 五月兰说道:

    先收藏了,晚点看!

  26. zzzworm说道:

    请问如何在IE下支持border-image拉伸超过100像素?还有其他更好的插件吗?

  27. lmx说道:

    必须顶一下,这么精彩的原创

  28. chin0811说道:

    看了flash流程图, 有种拨云见日的感觉. 感谢lz对普及css3的贡献.

  29. hushicai说道:

    这文章很不错,不过貌似border-image的图片最多可以有3张,呵呵,这里没有演示出来~

  30. 菜鸟说道:

    楼主v5 以前我都是潜水的,今天被一股霸气所征服

  31. nebel说道:

    学习到了。浅显易懂。
    一般没留言的习惯。今天留言下。 谢谢楼主。

  32. 可乐加糖说道:

    楼主写的很详细,只不过就是这样的属性只要碰到IE就草鸡了~~~~~~~~
    用不用此属性还得斟酌斟酌。

  33. cayden说道:

    博主,写的通俗易懂,谢谢

  34. cayden说道:

    确实很强大css3

  35. JackCheung说道:

    border-image太强大了,有个革命的意思,所有的浏览器赶快支持啊

  36. felicia帆说道:

    很给力,不得不赞句

  37. 龙子说道:

    以前一直没有详细看border-image这个属性,有点想当然了。
    博主,解释的很详细、透彻。

  38. 一路说道:

    厉害@!!

  39. 菜鸟飞啊飞说道:

    写的太好了,详细清楚,赞博主!!

  40. MOPVHS说道:

    大爱…谢谢你的详细讲解~~~

  41. classyuan说道:

    楼主啊,我太崇拜你了。看完这篇豁然开朗,顶~!