CSS3 background介绍

17 May

background应该是CSS里使用频率颇高的属性,简单实用。但参数偏多,本篇就介绍一下background的各种特性。

CSS3之前主要有5个属性:

  • background-color
  • background-image
  • background-repeat
  • background-attachment
  • background-position

CSS3增加了3个属性:

  • background-origin
  • background-clip
  • background-size

background-color:背景色,默认值transparent,不赘述。

background-image:背景图,默认值none。可用url指定图片地址,可以是相对地址,也可以是绝对地址,不赘述。

background-repeat:no-repeat,repeat-x,repeat-y,repeat(默认值),space,round。前4个效果见下图。左图no-repeat就是背景图的原始尺寸,依次是水平重复,垂直重复,全方位重复。有个两个细节要注意:

  1. 背景图是起始于盒子模型中padding-box的左上角,而非content区域的左上角。如果你设置了padding,padding区域也会被背景图覆盖。
  2. 重复都是正向反向两端重复。例如repeat-x,往右重复效果很明显,但仔细看发现也会往左重复(左边框底下也有图片),不要误以为只往右重复。同理repeat-y,也会往上重复(上边框底下也有图片)。同理repeat是全方位重复,4条边框底下均有图片

background-repeat

CSS3中可以允许设两个值,分别代表水平和垂直的重复。例如background-repeat: repeat repeat;等价于background-repeat: repeat;。看上去好像然并卵,要水平或垂直重复已经有repeat-x或repeat-y了,允许设两个值究竟有什么用呢?作用是和下面CSS3里新增的两个值(space,round)结合起来用,如果只允许单值是实现不了水平/垂直单向space或round效果的。

space表示两端平铺,保持背景图原始尺寸。round表示两端对齐,会适当拉伸背景图。例如左图background-repeat: space no-repeat;水平两端平铺,垂直不重复。右图background-repeat: round no-repeat;水平两端对齐,垂直不重复。左图好理解,不赘述。右图round no-repeat和repeat-x看起来效果差不多,但仔细看其实是有区别的,round会拉伸图片以实现两端对齐,但repeat-x是保持背景图原始尺寸的前提下简单重复。

background-repeat space round

用单值的话,就是水平垂直两方向重复。例如左图background-repeat: space;。右图background-repeat: round;

background-repeat space round

background-attachment:scroll(默认值),fixed,local。前两个表示背景图是否随页面滚动或固定。通常fixed用在html或body上。第三个local是CSS3里新增的,当有滚动条时可以让背景随元素内容滚动,即有滚动条时背景相对于元素内容固定。

例如在ul的顶部设一个阴影背景,提示用户到顶了(如下左图)。当用户滚动滚动条时,顶部阴影消失(如下右图)。即滚动条在顶部时,出现阴影,不在顶部时阴影消失:

background-attachment

ul {
    width: 5em;
    height: 7em;
    border: 1px solid silver;
    padding: .3em .5em;
    overflow: auto;
    background: radial-gradient(at top, rgba(0,0,0,.3), transparent 70%);
    background-repeat: no-repeat;
    background-size: 100% 10px;
    background-attachment: local;
}

这个效果在local属性未出现之前是很难实现的。如果你将background-attachment设成scroll,背景只会在页面发生滚动时才滚动,但显然ul元素内部滚动时页面不会发生滚动,因此顶部阴影将永远不会消失。只有通过CSS3新增的local属性,才能将背景和元素内容绑定,ul元素内部滚动时,背景阴影同时滚动,达到消失的效果。

background-position:背景图水平和垂直起点。默认值0% 0%,即起点是在padding-box(你可以用background-origin改成border-box或content-box)的左上角。可设百分比也可设px值。正值会往正向偏移(以左上角为起点,往右和往下是正反向,往左和往上是反方向)。例如左图background-position: -10px 10px;右图background-position: 10px -10px;(为演示效果均设成no-repeat)。50%可以用关键字center代替。

background-position

CSS3中增强了该属性,将两值扩展为四值,如background-position: left 10px top 10px;,前2个代表水平方向,后两个代表垂直方向。这样背景图的起点将不再局限于左上角,你可以更加灵活地掌控背景图的位置。

background-position

//代码依次是:
background-position: left 10px top 10px;
background-position: left 10px bottom 10px;
background-position: right 10px top 10px;
background-position: right 10px bottom 10px;

如果嫌指定left,right麻烦,其实用background-position配合calc也可以轻松实现定位,例如将图片定位到距离右下角20px的地方。我们不指定right,bottom,仍旧以左上角为原点:

background-position: calc(100% - 20px) calc(100% - 10px);

上面这5个属性是CSS1里就定义了,CSS3只不过做了适当的扩展。下面是介绍的是CSS3里新增的属性。

background-origin:content-box,padding-box(默认值),border-box。该属性决定了背景图片原点在盒子模型哪里。默认值padding-box表示背景图原点在content+padding区域。同理content-box表示背景图原点在content区域。border-box表示背景图原点在content+padding+border区域。左图content-box(div有5px的padding),中图padding-box,下图border-box(可以看出背景图原点是在边框外经处,背景图部分跑到了边框底部)

background-origin

background-clip:content-box,padding-box,border-box(默认值)。背景剪裁区域。我看完W3C简单的说明和例子后,发现该属性和上面background-origin非常像,实在难以理解区别在哪里。实际上是有区别的。background-origin是确定背景图片的原点起点位置,而background-clip是指背景剪裁区域。前者的对象是背景图片,后者的对象是整个背景。两者的区别如下图:

background-clip

//左图
background: red url(bg50.png) no-repeat;
background-origin: content-box;
//右图
background: red url(bg50.png) no-repeat;
background-clip: content-box;

同样设成了content-box。左图background-origin将背景图片的原点设为content区域左上角。右图background-clip设为content-box的意思是:将content区域外的所有背景相关内容(包括背景色和超出部分的背景图片)剪裁掉。

在上面代码的基础上,将左图background-origin和右图background-clip都改成padding-box

background-clip

左图background-origin将背景图片的原点设为padding-box区域左上角。右图background-clip设为padding-box的意思是:将padding-box区域外的所有背景相关内容剪裁掉,看效果只剪裁掉了border下面的背景色,而背景图片没有被剪裁。道理很简单,因为背景图片默认的background-origin就是padding-box,因此没有超出padding-box区域的部分。

在上面代码的基础上,将左图background-origin和右图background-clip都改成border-box

background-clip

原理和上面都一样,不再赘述。

background-size:px值,%百分比,cover,contain,auto(默认值)。在CSS2.1之前,我们是没有办法控制背景图片的大小的。CSS3可以用该属性来控制背景图片的大小。例如background-size: 10px 20px;第一个是width,第二个是height,如果只设一个值,第二个值将成为auto(意思是保持原始宽高比例)。

关键字cover将按比例缩放图片来填充满整个背景区域。contain将保持原图比例的前提下,缩放图片来填充背景区域。左图background-size: cover;,右图background-size: contain;

background-size

原图是150*200px,cover通过缩放会完全充满背景区域,但可能会出现图片扭曲或截断,因此多用在背景图片比容器小的情况下。contain会保证原图比例的前提下尽量填满背景区域,但可能出现没完全填满的情况,因此多用在背景图片比容器大的情况下。

小Tips:嫌cover,contain自适应缩放不居中的话,可以加上background-position: center;

background-size

至此background的各属性介绍完毕。我们可以单独指定background各属性,也可以将原始的5个属性合并到一起指定,CSS3新增的3个属性请单独指定。

未指定的属性将被浏览器自动设为默认值。如background: red;等价于background: red none repeat repeat scroll 0% 0%;。CSS3新增的3个属性也会被设为默认值:padding-box border-box auto

下面介绍下CSS3多背景属性

CSS3之前每个容器只能指定一张背景图片,要实现多个背景图片的效果,需要HTML端多个容器叠加,比较麻烦。CSS3开始可以直接在一个容器上指定多张图片。

指定多张图片时,只有background-color属性是无法指定多个的,因为该属性是隶属于容器而非背景图片的。你可以单独为多张图片指定background属性,也可以合并在一起指定。

单独为多张图片指定background属性格式:

background-image: url(bg.png), url(bg50.png), url(bgheader.jpg);
background-repeat: repeat-x, repeat-y, no-repeat;
background-attachment: scroll, scroll, scroll;
background-position: center, right 10px bottom 10px, left top; 
background-origin: content-box, padding-box, border-box;
background-clip: border-box, padding-box, content-box;
background-size: auto, 50% auto, 50% 50%;

各属性第一个逗号是图1,各属性第二个逗号是图2,各属性最后一个值是图3。上面代码最终效果是图4。从图中也可以看出层叠关系,第一个逗号的图1在最上层,依次往下是第二个逗号的图2和最后一个值的图3。当然最底层肯定是容器的background-color。

CSS3多背景属性

你也可以将各属性合并在一起写,中间仍旧用逗号隔开,效果和上图4是一样的:

background: url(bg.png) repeat-x scroll center,
	url(bg50.png) repeat-y scroll right 10px bottom 10px,
	url(bgheader.jpg) no-repeat scroll left top;
background-origin: content-box, padding-box, border-box;
background-clip: border-box, padding-box, content-box;
background-size: auto, 50% auto, 50% 50%;

不论你单独写还是合并写,最后加一个background-color属性(如果容器需要背景色)。

综合应用

现在用background实现边框为一张照片的效果:

background13

你可能会想到用border-image。但border-image的本质是图形复制,而我们希望边框图片随元素宽高的变化而自动变化,所以就无法用border-image了。(当然你可以试一下border-image,并改变元素大小,对比一下看看效果)

你可能还会想到用两层div,外层div的background加载图片,内层div的background设成白色即可。这样是可以实现的,但需要额外增加一层div标签,而我们希望只用一层div配合background就能实现。

我们的思路是:利用上面介绍的background的多背景属性,为div的background指定两层背景,底层背景加载图片,上层白色背景利用渐变的实色效果来实现(关于渐变实色你可以点这里

.borderImage {
    border: 1em solid transparent;
    background: linear-gradient(white, white),
		url(stone-art.jpg);
    background-size: cover;
    background-clip: padding-box, border-box;
    background-origin: border-box;
    width: 21em;
    padding: 1em;
    overflow: hidden;
    resize: both;
}

第一行设定border,指定为transparent让其透明。

第二行指定background。上层用linear-gradient实现白色背景,并指定background-clip为padding-box让其不要覆盖到border。下层背景加载图片,为了实现背景随元素大小而改变,需要指定background-size为cover。因为上层图片将background-clip设成了padding-box,因此需要为下层图片改回border-box。最后指定background-origin为border-box,否则默认padding-box的话,下层图片背景会出现重复,导致border里的图片非常诡异。

最下面加上resize方便你元素右下角拖动来改变元素大小,看看边框背景是否跟着等比例缩放,用border-image是无法实现这个效果的。

总结

background应该算CSS里一个比较基础的属性,本篇更多的是给自己零散的知识点做一个总结。以后对background有什么新的发现都可以往这篇里增加,这就像一颗种子,假以时日终会长成一颗小树苗。