CSS3之美(七):背景图像

CSS3 为背景图片引入了丰富的特性,这意味我们开发者对背景图片有了更多的掌控权。

多背景图片

CSS3 对现有的 background-* 属性进行了扩展,几乎所有的 background-* 属性现在都可以接受多个值,除了 background-color 属性。

下面我们介绍使用 background-image 属性为元素添加多个背景层:

1
2
3
4
5
div {
background-image: url('sunny.png'), url('child.png');
background-position: 95% 85%, 50% 50%;
background-repeat: no-repeat;
}

在示例代码中 background-image 使用了两张图片,但是在显示时,列表中的第一层图片(sunny.png)会成为最顶层,位于后面的图片将会按声明的顺序先后显示在它的下面。另外,background-position 属性值的顺序遵顼与 background-image 相同的顺序。

注意:background-repeat 属性只有一个唯一的值,如果一个属性的值的数量比其背景图片的数量少,那么这些值就会被重复。在上面的示例中,no-repeat 将会被应用到所有的背景层图片上。

我们可以对 background 简写属性使用多个值,和独立的属性一样,我们也只需要提供一个逗号隔开的列表。上面示例使用简写方式改写如下:

1
2
3
4
5
div {
background:
url('sunny.png') no-repeat 95% 85%,
url('child.png') no-repeat 50% 50%;
}

如果同时设置了背景图像 background-image 和 背景颜色 background-color,那么背景图像将覆盖在背景颜色之上。所以,如果我们需要背景颜色的话,那么在写属性代码时应该将其置于逗号隔开的列表的最后位置。

1
2
3
4
5
6
div {
background:
url('sunny.png') no-repeat 95% 85%,
url('child.png') no-repeat 50% 50%,
#000;
}

不过,老版本的浏览器将会忽略以上语法,并引用层叠中的前一条规则。所以,我们应该在使用多值之前在元素上声明一个属性,作为一种优雅降级方案。例如:

1
2
3
4
5
6
div {
background: url('sunny.png') no-repeat 50% 50%;
background:
url('sunny.png') no-repeat 95% 85%,
url('child.png') no-repeat 50% 50%;
}

在这种情况下,不支持的浏览器将会忽略使用多值的属性,然后使用在它之前的单值。不过,要注意在 IE 中,我们需要为这两者使用简写属性,因为如果我们使用 background-* 属性,它们就会优先于简写属性,不会有图片显示出来。

背景位置

CSS3 并没有新增与背景位置有关的属性,不过倒是为两个已有属性了增加了新的属性值。

background-attachment

第一个与背景位置相关的属性是 background-attachment,用于设置背景图是跟随对象滚动还是固定的。其原本只有两个值 fixedscroll,但CSS3 为其新增了一个值 local

  • fixed: 表示背景图相对于窗口固定位置。
  • scroll: 表示背景图相对于元素固定,也就是说当元素内容滚动时背景图不会跟随着滚动,因为背景图总要跟着元素本身,但背景图会随元素的祖先或窗口一起滚动。
  • local: 意味着背景图相对于元素固定,但是当元素滚动时背景图也会随之滚动,因为背景图总是要跟着内容。

background-position

第二个属性是 background-position,用于设置背景图开始显示的位置。其语法如下:

1
E { background-position: value; }

该属性默认值为 left top,即背景图从左上角开始显示。

它的属性值可以为数值、百分比值、关键字值。其中,数值和百分比值指定背景图填充的位置,可以为负值。属性值需要两个参数,第一个会被用于横坐标,第二个会被用于纵坐标,如果我们仅仅只设定了一个值,那么第二个会被默认设为 center

可用的关键字值有以下:

  • left <==> left center
  • right <==> right center
  • top <==> top center
  • bottom <==> bottom center
  • center <==> center center

以上关键字可以组合,所有合法的组合如下:

  • left top <==> top left
  • left center <==> center left
  • left bottom <==> bottom left
  • right top <==> top right
  • right center <==> center right
  • right bottom <==> bottom right
  • top left
  • top center <==> center top
  • top right
  • bottom left
  • bottom center <==> center bottom
  • bottom right
  • center center
  • center left
  • center right
  • center top
  • center bottom

示例,背景图在容器中居中显示:

1
2
3
div {
background: url('test.png') no-repeat 50% 50%;
}

而在 CSS3 中,background-position 属性允许最多提供 4 个参数值,如果提供 3 或 4 个参数值,那么每个 length 或 percentage 偏移值前都必须跟着一个关键字(不包括 center),偏移量相对于关键字所表示的位置进行偏移。

示例,假设背景图在容器中右下方,并且距离右边和底部各有 20px:

1
2
3
div {
background: url('test.png') no-repeat right 20px bottom 20px;
}

背景尺寸

CSS3 新增了一个属性 background-size,通过使用它我们能控制背景图片的缩放。该属性的值可以是一对长度或者百分比值、一个单独的长度或者百分比值(不允许负值),或者关键字。

该属性的默认值是 atuo,即以原图的宽高为准不变。

如果使用一对值,其语法是

1
2
3
4
E { background-size: width height; }
/* width 图像宽度
* height 图像高度
*/

如果使用单个值,则该值会被认为是宽度的大小,而高度则会使用默认值 auto

另外,还有两个可用的关键字如下:

  • contain: 背景图等比缩放,但是其宽高不会超过容器的长或宽,整个背景图始终会被包含在容器内。
  • cover: 背景图片等比缩放到容器的宽度或高度(向更大的那个值看齐),会完全覆盖容器,背景图像可能会超出其容器,即在容器中无法看到整个背景图的全貌

精确控制图片位置:显示截至位置和显示原点

在 CSS2 中,背景图定义的位置是相对于其包含元素的 padding 的外边界的,所有溢出都会扩展到边框之下。CSS3 引入了两个新的属性,可以对其进行更精确的控制。

background-clip

第一个属性是 background-clip,它设置盒模型的哪一部分成为背景显示的截至位置。其语法如下:

1
E { background-clip: value; }

background-clip 属性的取值如下:

  • 默认值
    • border-box
  • 可用的关键字值
    • border-box:背景图显示到 border 外边界处为止
    • padding-box:背景图显示到 padding 外边界处为止
    • content-box:背景图显示到 content 外边界处为止

该属性当前在 Opera 中的得到了实现,在 Firefox4 和 IE9 应该也没有问题。较老的 Firefox 版本使用的是非标准的实现,使用值 borderpadding 分别替代了 border-boxpadding-box,在属性上使用了专用的 -moz- 前缀。

Webkit 的情况较为复杂,它最早的实现使用了 borderpadding 值,就像早期 Firefox 一样,并且也使用了 content 关键字代替了 content-box,而且在所有属性上都具有 -webkit- 前缀。较新的版本使用 border-box padding-box content-box,但仍然使用带前缀的属性。最新的 Webkit 版本,使用 border-box padding-box 的时候没有了前缀,但在使用 content-box 时仍需要前缀。鉴于以上情况,若要编写跨浏览器代码,或许像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
E1[class~='bord'] {
-moz-background-clip: border;
-webkit-background-clip: border;
-webkit-background-clip: border-box;
background-clip: border-box;
}
E2[class~='padd'] {
-moz-background-clip: padding;
-webkit-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
}
E3[calss~='cont'] {
-webkit-background-clip: content;
-webkit-background-clip: content-box;
background-clip: content-box;
}

background-origin

第二个属性是 background-origin,它可用来设置背景开始显示的原点。该属性的取值同 background-clip 属性可用的关键字值一样,具体可用取值如下:

  • 默认值

    • padding-box
  • 可用的关键字值

    • content-box
    • padding-box
    • border-box

这个属性与之前 background-clip 属性的区别为:

  • background-clip 用于指定元素对象的背景图显示的截至位置
  • background-origin 是用于指定元素对象的背景图像计算 background-position 时的参考原点,也就是说,这个属性是与 background-position 属性一起配合使用。background-position 负责设定背景图从容器的哪一块位置开始,而 background-origin 则负责更精确地控制是从容器盒模型的哪一层边界开始。

background-clip 一样,Opera 和最新的 Webkit 浏览器对 background-origin 的实现和规范一致,而 Firefox4 和 IE9 应该也是相同的。较老的 Firefox 和更老一些的 Webkit 版本并没有实现这个属性的标准版本,它们使用带有前缀的属性实现了三个像 border padding content 一样的可能值,而老一点的 Safari5 之前的 Webkit 版本要求使用正确的值,也是通过带前缀的属性实现。因此,跨浏览器代码看上去如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
E1[class~='bord'] {
-moz-background-origin: border;
-webkit-background-origin: border;
-webkit-background-origin: border-box;
background-origin: border-box;
}
E2[class~='padd'] {
-moz-background-origin: padding;
-webkit-background-origin: padding;
-webkit-background-origin: padding-box;
background-origin: padding-box;
}
E3[class~='cont'] {
-moz-background-origin: content;
-webkit-background-origin: content;
-webkit-background-origin: content-box;
background-origin: content-box;
}

背景重复

background-repeat 属性可以控制背景图的重复方式,其取值如下:

  • 默认值

    • repeat: 水平和垂直方向都重复
  • 可用的关键字取值

    • no-repeat:不重复
    • repeat
    • repeat-x: 仅在水平方向重复
    • repeat-y: 仅在垂直方向重复

通过设置这些值中的某一个可以使背景图沿着元素的某一轴线(或者两条轴线)进行平铺,但无法实现更为精确的控制。CSS3 引入了两个新的属性值:

  • space: 背景图以相同的间距(除了第一次和最后一次)平铺且填充在整个容器或某个方向。不会对背景图进行裁剪和缩放,容器内重复的背景图之间可以看到有明显间距
  • round: 会缩放背景图,尽可能多地进行重复直到适应且填充整个容器。这个属性值将计算能够水平和垂直填充包含元素的图片的最大完整数量。

background-*属性简写

background-* 独立属性纷杂繁多,简写时需要按照以下规则:

1
background: background-image background-position/background-size background-repeat background-attachment background-origin background-clip background-color;

下面以示例说明:

1
2
3
4
5
6
div {
background:
url('test1.png') no-repeat scroll 10px 20px/50px 60px content-box padding-box,
url('test2.png') no-repeat scroll 10px 20px/70px 90px content-box paddign-box,
#aaa;
}

由于 background-color 只能设置一次,且由于写在前面的背景会叠在之后的背景上,所以背景色通常都定义在最后一组上,避免背景色将背景图遮盖。

上面示例代码等价于以下独立属性写法:

1
2
3
4
5
6
7
8
9
10
div {
background-image : url('test.png'), url('test2.png');
background-repeat : no-repeat, no-repeat;
background-attachmnet : scroll, scroll;
background-position : 10px 20px, 10px 20px;
background-size : 50px 60px, 70px 90px;
background-origin : content-box, content-box;
background-clip : padding-box, padding-box;
background-color : #aaa;
}

如果定义了多个背景图片,而其他属性的参数值只有一个,那么这些参数值就会被应用到所有背景图上,根据此原则,可以对上面代码进行缩写:

1
2
3
4
5
6
7
8
9
10
div {
background-image : url('test2.png'), url('test2.png');
background-repeat : no-repeat;
background-attachment : scroll;
background-position : 10px 20px;
background-size : 50px 60px, 70px 90px;
background-origin : content-box;
background-clip : padding-box;
background-color : #aaa;
}

另外,如果定义了多个背景图片,而 background-originbackground-clip 设置了相同的值,还可以简写为:

1
2
3
4
5
6
div {
background:
url('test1.png') no-repeat scroll 10px 20px/50px 60px padding-box,
url('test2.png') no-repeat scroll 10px 20px/70px 90px padding-box,
#aaa;
}