CSS3(二)—— CSS3框模型

通过 CSS3,您能够创建圆角边框,向矩形添加阴影,使用图片来绘制边框 - 并且不需使用设计软件,比如 PhotoShop。

在本章中,您将学到以下边框属性:

border-radius

box-shadow

border-image

浏览器支持

Internet Explorer 9+ 支持 border-radius 和 box-shadow 属性。

Firefox、Chrome 以及 Safari 支持所有新的边框属性。

注释:对于 border-image,Safari 5 以及更老的版本需要前缀 -webkit-。

Opera 支持 border-radius 和 box-shadow 属性,但是对于 border-image 需要前缀 -o-。

CSS3 圆角边框

例子:(1)border-radius:102px;

(2) border-radius:40px/80px; //border-radius是一种缩写方法。如果“/”前后的值都存在,那么“/”前面的值设置其水平半径,“/”后面值设置其垂直半径。

(3)border-radius:10px 20px 40px 60px; // 书写顺序支持 上,右,下,左;

(4)border-radius:20px 40px;// 左上和右下为20px;右上和左下为40px;

(5)border-radius:10px 20px 40px; // 左上为10px;右上和左下为20px;右下为40px;

(6)border-radius:10px 20px 40px 60px/20px 40px 80px 120px;

(7)border-radius:50%; // 圆形,如果宽高相同,则是正圆;

CSS3 边框阴影

语法:

box-shadow:insetx-offset y-offset blur-radius spread-radius color

也就是:

对象选择器 {box-shadow:投影方式 X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色}

取值:

box-shadow属性至多有6个参数设置,他们分别取值:

阴影类型

此参数是一个可选值,如果不设值,其默认的投影方式是外阴影;如果取其唯一值“inset”,就是将外阴影变成内阴影,也就是说设置阴影类型为“inset”时,其投影就是内阴影;

X-offset

是指阴影水平偏移量其值可以是正负值可以取正负值,如果值为正值,则阴影在对象的右边,反之其值为负值时,阴影在对象的左边;

Y-offset

是指阴影的垂直偏移量,其值也可以是正负值,如果为正值,阴影在对象的底部,反之其值为负值时,阴影在对象的顶部;

阴影模糊半径:

此参数是可选,,但其值只能是为正值,如果其值为0时,表示阴影不具有模糊效果,其值越大阴影的边缘就越模糊;

阴影扩展半径

此参数可选,其值可以是正负值,如果值为正,则整个阴影都延展扩大,反之值为负值是,则缩小

阴影颜色

此参数可选,如果不设定任何颜色时,浏览器会取默认色,但各浏览器默认色不一样,特别是在webkit内核下的safari和chrome浏览器将无色,也就是透明,建议不要省略此参数。

我们这里还涉及到一个各浏览器前缀的问题,比如说Mozilla内核的-moz,webkit内核的-webkit。经测试在最新版的Firefox和Google Chrome浏览器都无需加上前缀,但在safari中还是需要前缘的,为了能兼容支持的各大浏览器,我们在书写box-shadow的格式应该这样

//Firefox4.0-

-moz-box-shadow: 投影方式 X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色;

//Safari and Google chrome10.0-

-webkit-box-shadow: 投影方式 X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色;

//Firefox4.0+ 、 Google chrome 10.0+ 、 Oprea10.5+ and IE9

box-shadow: 投影方式 X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色;

box-shadow的特征:

较之ps制作出来的图片相比,CSS3的box-shadow可以通过改变其参数得到不同的效果,如:改变阴影偏移量的设置,我们可以使用阴影只在对象的上下左右的任一边出现,也可以让其出现在其中的某几个边上;其二可以随时调节阴影大小,边缘模糊度,阴影颜色,其三可以随时更改为内阴影,另外还可以设置多个阴影效果

我们先来看一个简单的实例:

.demo1{

-webkit-box-shadow:3px3px3px;

-moz-box-shadow:3px3px3px;

box-shadow:3px3px3px;

Firefox/Opera下效果

Safari/Chrome下效果

回到上面那个实例,其实在webkit内核的浏览器Safari、Google Chrome里不会有任何阴影效果,虽然W3C标准里说颜色是可选择的,但是在没有给出颜色的时候 ,safari/chrome和firefox表现不同,在webkit内核的浏览器下阴影表现为透明色而mozilla和oprea下表现为黑色。基于这样的原因,大家在使用box-shadow时不要忘了加上阴影颜色的值。

根据上面的现像,我们来看一个box-shadow有关阴影是否会被计算为内容的实例。

我们把外面div设置为100px*100px,里面div设置为60px*60px,并在里面的div上加上一个向下向右偏移50px的绿色阴影,我们看看多出来的阴影会怎么样?

  .outer {
    width: 100px;
    height: 100px;
    border: 1px solid #ccc;
  }
  .inter {
    width: 60px;
    height: 60px;
    margin: 10px auto;
    background: #f69;
    -webkit-box-shadow: 50px 50px green;
    -moz-box-shadow: 50px 50px green;
    box-shadow: 50px 50px green;
  }

从各大浏览中的效果我们可以看出,阴影多出来的阴影会撑破容器跑出来。标准里有一张图,描述了box-shadow的工作方式,这张图直观告诉我们如何使用box-shadow

这张图可以告诉我们很多信息,比如说borer-radius圆角,阴影扩展、阴影模糊以及padding是如何影响对象阴影的:非零值的border-radius将会以相同的作用影响阴影的外形,但border-image不会影响对象阴影的任何外形;对象阴影同box模型的层次一样,外阴影会在对象背景之下,内阴影会在边框之下背景之上。所以整个层级就是:边框>内阴影>背景图片>背景颜色>外阴影。因为大家都知道,我们的背景图片是在背景颜色之上的。

IE滤镜方法:

在前面我们讲过,IE9以下是不支持CSS3的box-shadow的,但为了处理这个兼容问题,我们可以在IE下使用IE的shadow阴影滤镜来实现:

filter: progid:DXImageTransform.Microsoft.Shadow(color=’颜色值’, Direction=阴影角度(数值), Strength=阴影半径(数值));

注意:该滤镜必须配合background属性一起使用,否则该滤镜失效。除了使用滤镜的方法外,我们还有一种方法可以实现IE下的效果。那就是使用jQuery的插件jquery.boxshadow.js。那么具体如何使用呢?其实很简单,你先下载这个jquery.boxshadow.js插件到你的项目中,接着把jquery版本库和jquery.boxshadow.js加载到页面上,如:



然后你可以创建一个单独的js文件来处理,或者直接在页面的里欠入一个,我们这里就只例出一个直接在head插入的解决办法:

 $(document).ready(function(){
    if($.browser.msie) {
      $('.demo1').boxShadow(0,0,5,"#888"); //demo1元素使用了box-shadow
      $('.demo2').boxShadow(-10,-10,5,"#f36"); //demo2元素使用了box-shadow
    }
  });

上面我们了解了CSS3的box-shadow相关基础知识,那么下面我们通过一些实例来巩固一下box-shadow的具体用法:

如果没有进行特殊说明,我们这里的实例所用的HTML代码都如下,只是改变第二个class名称,如demo1 demo2等:

.demo { width: 100px; height: 50px; background: #f69; }

提醒大家:为了节约时间,下面的css代码中我只写了一个box-shadow,但是大家在实际应用中一定要记得把:-webkit-box-shadow和-moz-box-shadow加上去,不然在safari和chrome浏览器下是会没有任何效果的,这个我们在前面提过,此处不详说。

效果一:单边效果

 .dome2 {
   box-shadow: -2px 0 0 green, //左边阴影
   0 -2px 0 blue, //顶部阴影
   0 2px 0 red, //底部阴影
   2px 0 0 yellow; //右边阴影
 }

上例中,我们分别对对象的四个边进行了box-shadow的设置,只不过我们使用了多层次的box-shadow应用,如果只需要在对象某一边应用阴影时,我们可以删除不使用阴影的设置。给对象四边设计阴影,我们是通过改变x-offset和y-offset的正负值来实现,其中x-offset为负值时,生成左边阴影,为正值时生成右边阴影,y-offset为正值是生成底部阴影,为负值时生成顶部阴影。并且把模糊半径设置为0,如果不设置为0的话那么其他三边也将会有阴影,并且此处还涉及到一个多阴影的顺序问题。当给同一个元素使用多个阴影属性时,需要注意它的顺序,最先写的阴影将显示在最顶层,如我们将上面的实例变一下,给其加上模糊值,将更能看出效果:

.demo3 {
    box-shadow: -2px 0 5px green,0 -2px 5px blue,0 2px 5px red,2px 0 5px yellow;
  }

这样我们上例中:左边的放在了第一,其green阴影色在顶边的blue上,而顶边的blue在又在右边的yellow上,右这的yellow却在底边的red上。所以应用多次阴影的写法一定要注意其顺序问题,特别的当阴影的模糊值不一样的情况之下,另外有些网站介绍说可以写成下面的形式,但我经过多个浏览器测试,这种写法是无效的,

  .demo4 {
    /*这种写法是错误的(,网上有介绍说可以这样书写,但我测试多次未见效果,所以本人提倡不要这样书次,以免造成不必要的错误)*/
    box-shadow: -2px 0 0 green,box-shadow: 0 -2px 0 blue,box-shadow: 0 2px 0 red,box-shadow: 2px 0 0 yellow;
  }

从上图的效果中也再一次证明了上面的写法是不正确的,希望大家在实际应用中时一定要注意多层次阴影的书写方法。同时也提醒大家在网上看相关资料时一定不能尽信,最好是能自己抽空验正一下。

在使用多层次的阴影时还需注意一个细节问题,如果前面的阴影模糊值小于后面的阴影模糊值,那么前面的显示在后面之上,如果前面阴影的模糊值大于后面的阴影模糊值,那么前面的阴影将遮住后面的阴影效果。如下面例子:

 /*第一个阴影模糊半径值小于第二阴影模糊半径*/
 .demo5 {
   box-shadow: 0 0 5px red,0 0 15px blue;
 }
  
 /第一个阴影模糊半径大于第二阴影模糊半径*/
 .demo6 {
   box-shadow: 0 0 15px red, 0 0 5px blue;
 }

实例效果再次证明:左图中我们可以看见红色阴影在兰色阴影之上并没有遮盖蓝色阴影,因为我们红色的阴影模糊值只有5px,比蓝色的15px模糊值要小;而右图中我们只能看到红色的阴影,那是因为我们第一个红色阴影的模糊半径大于第二个兰色的模糊半径,所以红色的阴影把蓝色的阴影遮盖住了。这一点大家可记住了。

效果二:四边具有相同的阴影效果(只设置阴影模糊半径和阴影颜色)

  .demo7 {
    box-shadow: 0 0 5px rgb(250,0,0);
  }

我们在这里设置的是HEX值,我们也可以应用css3的rgba值给box-shadow的阴影颜色上,这样的好处是,box-shadow阴影色多了一个alpha透明值 ,如下面的实例:

 .demo8 { 
   box-shadow: 0 0 5px rgba(250,0,0,0.5);
 }

对比上面两个例子,前一个例子我们没有应用透明值,而后面一个例子我们应用了0.5的透明值,相比之下后面的阴影是不是更浅。当然在实践应用中您可以根据自己的需求进行设置。

效果三:四边具有相同的阴影(只设置阴影扩展半径和阴影颜色)

 .demo9 {
  box-shadow: 0 0 0 1px red;
 }

从效果中大家想想这种效果是不是跟我们在元素中的boder: 1px solid red;属性产生的效果很相似的呀。对的,box-shadow不单可以制作出阴影的效果,我们还可以利用其扩展半径这个值,来给对象制作出类似于边框的样式。下面我们来看一个对比的实例:

  /*边框效果*/
  .demo10 {
    border: 1px solid red;
  }
  /*阴影效果*/
  .demo11 {
    box-shadow: 0 0 0 1px red;
  }

实际上利用box-shadow来制作边框,只能说看上去像边框,但实质其并非边框,他和border还是有本质上的区别。从上面的效果图中我们明显的可以看出左边的box要比右边的box低那么1px的,这样一来随着其扩展半径值越大,两者之间的相差就更大,如:

 .demo12 {
   border: 20px solid red;
 }
	
 .demo13 {
   box-shadow: 0 0 0 20px red;
 }

我们接着来看demo12和demo13两个demo在firebug下的layout图:

结合上图两者在firebug下的layout图,更证实了我们前面所讲的阴影不会影响页面的任何布局:demo12的边框被计算了宽度,但demo13的阴影浏览器却忽略不计,所以借住这个特点,我们阴影所模拟的边框理可以自由的使用,但必须要注意其层级关系。

CSS3 边框图片

一、border-image的兼容性

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

二、熟悉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)。

这张图能够帮助我们更好的理解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; 
    -moz-border-image:url(../image/border.png) 27; 
    -webkit-border-image:url(../image/border.png) 27; 
    border:double orange 1em;
}

结果:

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

效果分析:

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

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

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

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

CSS代码:

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

结果:

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

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

CSS代码:

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

结果:

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

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

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

4、上实例样式缩写

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

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

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

border-image绘制原理简述

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

1、调用边框图片

border-image的url属性,通过相对或绝对路径链接图片。

2、边框图片的剪裁

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

3、剪裁图片填充边框

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

4、执行重复属性

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

5、完成绘制,实现效果

绘制原理动画示意,本flash动画以第一个demo效果做示例,请点击其中的“下一步”按钮,可看到一步一步的演示:

四、border-image的一些应用

自适应的圆角效果

使用图片如下:

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

.border_image{
    -moz-border-image:url(../image/rounded_corner.png) 20/10px; 
    -webkit-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这类浏览器不支持,但是并不代表他们无法实现类似的效果。例如利用,可以让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下貌似也有点问题。

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

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

六、总结

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

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

七、参考内容

1、百度百科,九宫格:

2、W3C官方文档:

3、CSS3中文手册

4、Meet a ninja living in browsers

如果您发现文章中有表述不准确或是有相关问题需要交流可以通过评论或是去这里进行提问交流。

原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[]

混合高斯模型GMMS的EM算法实现

最近学习机器学习课程,需要实现混合高斯模型的求解。因为混合高斯模型的优化函数,似然函数难以求导优化,所以使用EM算法优化。下面是EM算法的实现。主要参考Andrew Ng的讲义上的公式实现的。

其中,j代表第几个类别,i代表第几个样本数,phi(j)代表类别出现的概率,即p(z(i)=j; phi)。数据满足的模型是混合高斯模型,即p(x|z)是高斯分布,由多个高斯分布以一定的权重相加。下面用matlab实现混合高斯模型。

%by alex
% 说明只需要改变数据X,迭代次数TIME,要分类的类别M即可
clear all;clc
%数据一
% MU1    = [1 2];
% SIGMA1 = [1 0; 0 0.5];
% MU2    = [-1 -1];
% SIGMA2 = [1 0; 0 1];
% X = [mvnrnd(MU1, SIGMA1, 1000); mvnrnd(MU2, SIGMA2, 1000)];
% 
% scatter(X(:,1), X(:,2), 50, '.')
% 数据二
MU1    = [1 2];
SIGMA1 = [1 1; 1 2];
MU2    = [-1 -1];
SIGMA2 = [1 0; 0 1];
MU3    = [-1 -5];
SIGMA3 = [1 0; 0 3];
X = [mvnrnd(MU1, SIGMA1, 1000); mvnrnd(MU2, SIGMA2, 1000); mvnrnd(MU3, SIGMA3, 1000);];
%数据三
% MU1    = [1 2 3];
% SIGMA1 = [1 0 0; 0 0.5 0;0 0 3];
% MU2    = [-1 -1 -1];
% SIGMA2 = [1 0 0; 0 1 0;0 0 1];
% MU3    = [-1 -5 -2];
% SIGMA3 = [1 0 0; 0 3 0; 0 0 2];
% X = [mvnrnd(MU1, SIGMA1, 1000); mvnrnd(MU2, SIGMA2, 1000); mvnrnd(MU3, SIGMA3, 1000);];
%%%%%%%%%%%%%% EM algorithm %%%%%%%%%%%
%用M改变类别数,TIME改变迭代次数
%求数据的整体协方差Covariance
CC = cov(X);
M = 3;   %M代表类别
TIME = 1000; %迭代次数
[N, D] = size(X);  %N为样本总数,D为特征个数
%初始化迭代参数
phi = rand(1,M);
phi = phi./sum(phi);
U = zeros(1,D);
init_u = zeros(M,D);
for i=1:D
    U(i) = mean(X(:,i));
end
for i=1:M
    init_u(i,:) = U(1:D)+i-1;
end
C = cell(1,M);
for i = 1:M
    C{i} = CC;
end
w = zeros(length(X),M);
mol_w = zeros(length(X),M);
den_w = zeros(length(X),M);
last_time = 0;
for k=1:TIME
    %E_step
    tmp = zeros(N,1);
    for i = 1:M
        tmp = tmp + phi(i)*mvnpdf( X, init_u(i,:), C{i} ); %求权系数的分母
    end
    for j = 1:M
        mol_w(:,j) = phi(j)*mvnpdf(X, init_u(j,:), C{j} );   %求权系数的分子
        den_w(:,j) = tmp;
        w = mol_w./den_w;
    end
    %M_step
    last_time = init_u(1,1);    %用于判断迭代次数
    for j = 1:M
        phi(j) = sum(w(:,j))/length(X);        %更新权重
        init_u(j,:) = w(:,j)'*X/sum(w(:,j));   %更新均值
        X_mean = X - repmat(init_u(j,:), N ,1);
        temp_w = repmat(w(:,j)',D,1);
        tmp_C = temp_w.*X_mean'*X_mean;
        C{j} = tmp_C./sum(w(:,j));              %更新方差
    end
    if(abs(init_u(1,1)-last_time) <= 0.000001)  %迭代次数判断
        iter_time = k
        break;
    end
end
%输出参数
phi
for j=1:M
    fprintf('第 %d 类',j)
    mu = init_u(j,:)
    sigma = C{j}
end
%在数据的特征为2维时,画出三维曲面图
if(D == 2)
    x = sym('x',[1,D]);     %定义符号数组
    pdf_u = sym('pdf_u',[M,D]);  %定义符号矩阵
    pdf_out = sym('pdf_out',[1,M]);
    for j=1:M
        pdf_u(j,:) = x - init_u(j,:);
        pdf_out(j) = phi(j)*exp(-0.5*pdf_u(j,:)*inv(C{j})*pdf_u(j,:)')/(2*pi*sqrt(det(C{j})));
    end
    g = sum(pdf_out);
    
    figure;
    ezsurf(g)
    title('混合高斯概率密度函数')
    
    figure
    ezcontour(g)
    title('混合高斯概率密度函数俯视图')
end

本站内容来自用户投稿,如果侵犯了您的权利,请与我们联系删除。联系邮箱:835971066@qq.com

本文链接:http://news.xiuzhanwang.com/post/573.html

发表评论

评论列表

还没有评论,快来说点什么吧~

友情链接: