3.6 背景

本章的主题是定位元素,关于定位元素,最后要讲的一个主题是背景。背景支持为元素添加背景颜色和背景图片。要是你使用过Adobe Photoshop或Adobe Fireworks的话,一定知道图层这个概念。CSS里也一样,每个元素盒子都可以想象成由两个图层组成。元素的前景层包含内容(如文本或图片)和边框,元素的背景层可以用实色填充(使用background-color属性),也可以包含任意多个背景图片(使用background-image属性),背景图片叠加在背景颜色之上。

在CSS3被浏览器实现之前,只能在背景颜色上添加一张背景图片。而现在,我们可以为背景图层添加多张图片(以及CSS3渐变)。为了让大家对元素盒子的图层有更直观的认识,下面我们把本章开头的盒模型示意图改成三维透视图,如图3-31所示。

enter image description here图3-31 这个盒模型示意图展示了元素的前景和背景层

图中的文字:背景颜色、背景图片、内边距、外边距、边框、屏幕上看到的效果

3.6.1 CSS背景属性

CSS规定以下与背景相关属性。

  • background-color
  • background-image
  • background-repeat
  • background-position
  • background-size
  • background-attachment
  • background(简写属性)
  • background-clipbackground-originbackground-break(目前尚未得到广泛支持)这些属性可以让我们控制背景图层的方方面面。下面我们就来一个一个地讲解。

3.6.2 背景颜色

background-color是背景属性中最简单的,通过它可以设定元素的颜色。然后,元素就会以设定的颜色填充背景图层,如图3-32所示。

  1. body {background-color:#caebff;}
  2. p {/*盒子布局样式*/
  3. font-family:helvetica, arial, sans-serif; font-size:18px;
  4. width:350px; margin:20px auto; padding:10px;
  5. /*这个例子中讨论背景和前景样式*/
  6. background-color:#fff; color:#666; border:4px solid;
  7. }

enter image description here图3-32 bodybackground-color是蓝绿色,段落的background-color是白色,前景色color是灰色,前景色既影响文本,也影响边框

这个例子除了演示怎么给元素添加背景色,还演示了前景色的作用范围,也就是前景色会影响元素的内容和边框。当然,有一个前提条件,就是在使用border设定边框的样式和宽度,而没有设定边框颜色(或者没有使用border-color单独设定边框颜色)的情况下,边框会使用color属性设定的字体颜色。默认颜色是黑色。如果你想让边框的颜色有别于文本,就需要单独设定。

3.6.3 背景图片

图3-33是一张包含圆形图案的图片,本节我们就它来示范background-imagebackground-repeat 属性。

enter image description here图3-33 为包含圆形图案的图片添加了边框,圆形四周有空白

接下来,我们通过background-image属性把这张包含圆形图案的图片放到元素的背景层上,结果如图3-34所示。

  1. p {
  2. font-size:28px;
  3. font-family:helvetica, arial, sans-serif;
  4. width:345px;
  5. height:110px;
  6. margin:20px auto;
  7. padding:10px;
  8. color:#000;
  9. border:4px solid #aaa;
  10. background-color:#fff;
  11. background-image:url(images/blue_circle.png);
  12. }

enter image description here图3-34 比元素小的背景图片会在水平和垂直方向上重复出现,直至填满整个背景空间

由此可见,默认情况下背景图片会以元素左上角为起点,沿水平和垂直方向重复出现,最终填满整个背景区域。正是因为以元素左上角为原点,所以元素盒子底部和右侧的圆形图案都只显示了一部分。要注意的是,指定背景图片来源的方式,与img标签中的方式不同,要这样:

  1. background-image:url(图片路径/图片文件名)

图片地址两边不用加引号,当然加了也没问题。

要改变默认的水平和垂直重复效果,可以修改background-repeat属性;要改变背景图片的起点,可以修改background-position属性。

3.6.4 背景重复

控制背景重复方式的background-repeat属性有4个值。默认值就是repeat,效果就是图3-34中所示的水平和垂直方向都重复,直至填满元素的背景区域为止。另外3个值分别是只在水平方向重复的repeat-x、只在垂直方向上重复的repeat-y和在任何方向上都不重复(或者说只让背景图片显示一次)的no-repeat 。这几个值的效果如图3-35所示。

enter image description here图3-35 4个不同background-repeat值的效果

这几种重复方式的用法有很多种。比如,repeat-xrepeat-y可以用来实现装饰性的边框效果,而no-repeat则控制背景图片只出现一次。除了背景图片、背景重复之外,另一个相关的控制选项是background-position,我们放在下一节介绍。

在此之前先提醒大家一句,CSS3还规定另外两个值(但尚未得到浏览器支持),以控制背景图片重复确切的次数,即所有图片都是完整的,不会出现半张图片的现象。

  • background-repeat:round:为确保图片不被剪切,通过调整图片大小来适应背景区域。
  • background-repeat:space,为确保图片不被剪切,通过在图片间添加空白来适应背景区域。

3.6.5 背景位置

用于控制背景位置的background-position属性,是所有背景属性中最复杂的。background-position属性有5个关键字值,分别是topleftbottomrightcenter,这些关键字中的任意两个组合起来都可以作为该属性的值。比如,top right表示把图片放在元素的右上角位置,center center把图片放在元素的中心位置。事实上,这都是很含糊的说法,下面我们就来详细解释。

千万要注意,background-position属性同时设定元素和图片的原点。原点决定了元素和图片中某一点的水平和垂直坐标。默认情况下,background-position的原点位于左上角。换句话说,元素的左上角和图片的左上角是对齐的,随后图片向各个方向重复,都是以左上角为起点。图3-35中所示就是默认以左上角为原点的情形。

有了这个基本共识之后,下面我们就在实践中学习background-position属性,仍以图3-35中的第一种情况为例。第一情况下,background-position属性的默认值top left控制着水平和垂直方向重复的起点。那我们看一看,把起点位置改为center center之后会有什么不一样(结果参见图3-36)。

  1. /*center center的简化写法*/
  2. p#center {background-position:center;}

只给background-position设定一个关键字值,则另一个也会取相同的值(比如这里就相当于写了background-position:center cetner)。

enter image description here图3-36 background-position:center center设定图片中心点与元素中心点重合,然后再向各个方向重复

比较修改前后的结果会发现,第二段中的背景图片是以段落的中心点为起点,然后再向水平和垂直方向重复。

好了,换一种思路。这次我们用百分比来设定位置,结果如图3-37所示。

  1. div {
  2. height:150px;
  3. width:250px;
  4. border:2px solid #aaa;
  5. margin:20px auto;
  6. background-image:url(images/turq_spiral_150.png);
  7. background-repeat:no-repeat;
  8. background-position:50% 50%;
  9. }

enter image description here图3-37 使用background-position把背景图片居中

我听见有人小声嘀咕:“为什么文本也跟着垂直居中了呢?”哈哈,这是因为我把line-height设定成了元素的高度,而行高是在文本行上下平均分配的。此外,我还把text-align设定为center,把文本水平居中。这样就让文本跟背景图片一样,在两个方向上都居中了。

通过把background-position设定为50% 50%,把background-repeat设定为no-repeat,实现了图片在背景区域内居中的效果。

背景位置的值

设定背景位置时可以使用三种值:关键字、百分比、绝对或相对单位的数值。可以使用两个值分别设定水平和垂直位置。

关键字指的顺序不重要,left bottombottom left意思相同。为了设定的值在所有浏览器中都有效,最好不要混用关键字值与数字值。

使用数值(比如40% 30%)时,第一个值表示水平位置,第二个值表示垂直位置。要是只设定一个值,则将其用来设定水平位置,而垂直位置会被设为center

在使用关键字和百分比值的情况下,设定的值同时应用于元素和图片。换句话说,如果设定了33% 33%,则图片水平33%的位置与元素水平33%的位置对齐。垂直方面也一样。图3-37所示也是一个例子,那是通过center center把图片的中心点定位在了元素的中心点。

像素之类的绝对单位数值就不一样了。要是用像素单位来设定位置,那么图片的左上角会被放在距离元素左上角指定位置的地方。

有意思的是,还可以使用负值。这样就可以把图片的左上角定位到元素外部,从而在元素中只能看到部分图片。当然,给图片设定足够大的正值,也可以把图片的右下角推到元素外部,从而在元素中也只能看到部分图片。位于元素外部的那部分图片不会显示。

3.6.6 背景尺寸

background-size是CSS3规定的属性,但却得到了浏览器很好的支持。这个属性用来控制背景图片的尺寸,可以给它设定的值及含义如下。

  • 50%:缩放图片,使其填充背景区的一半。
  • 100px 50px:把图片调整到100像素宽,50像素高。
  • cover:拉大图片,使其完全填满背景区;保持宽高比。
  • contain:缩放图片,使其恰好适合背景区;保持宽高比。仍然使用图3-37居中背景图片的CSS规则,但把图片换一换,再分别设定上面列出的background-size属性的几个值,会得到图3-38所示的效果。

enter image description here图3-38 给一个居中的不重复的背景图片应用不同的background-size值的效果

这个新属性为我们控制背景图片提供了更多可能性。使用这个属性需要注意,别把本来很小的图片拉得太大,那样会导致图片质量失真。

3.6.7 背景粘附

background-attachment属性控制滚动元素内的背景图片是否随元素滚动而移动。这个属性的默认值是scroll,即背景图片随元素移动。如果把它的值改为fixed,那么背景图片不会随元素滚动而移动。

background-attachment:fixed最常用于给body元素中心位置添加淡色水印,让水印不随页面滚动而移动。

实现这种效果的CSS规则如下。

  1. body {
  2. background-image:url(images/watermark.png);
  3. background-position:center;
  4. background-color:#fff;
  5. background-repeat:no-repeat;
  6. background-size:contain;
  7. background-attachment:fixed;
  8. }

没错,关于背景图片的规则写起来有点费劲,因为属性名太长了。别担心,使用简写属性background就可以在一条声明里设置所有值。

3.6.8 简写背景属性

background属性可以用来设定所有背景相关的值。比如,前面那个background-attachment的例子使用简写的background属性,可以写成这样一条规则:

  1. body {background:url(images/watermark.png) center #fff no-repeat contain fixed;}

声明中少写了哪个属性的值(比如没写no-repeat),就会使用相应属性的默认值(repeat)。

3.6.9 其他CSS3背景属性

CSS3又新增了一些新的背景属性,这里来简单介绍一下。不过,这些属性受支持的程度并不一致,如果你想使用它们,别忘了测试自己的页面在这些属性不可用时会出什么问题。要不,就使用Modernizr来检测浏览器对它们的支持情况,并为不支持它们的浏览器提供替代CSS。

Modernizr是一个JavaScript库,用于检测用户浏览器支持哪些HTML5和CSS3功能。更多信息,请参考这个网址:http://modernizr.com

  • background-clip。控制背景绘制区域的范围,比如可以让背景颜色和背景图片只出现在内容区,而不出现在内边距区域。默认情况下,背景绘制区域是扩展到边框外边界的。
  • background-origin。控制背景定位区域的原点,可以设定为元素盒子左上角以外的位置。比如,可以设定以内容区左上角作为原点。
  • background-break。 控制分离元素(比如跨越多行的行内盒子)的显示效果。

有关这些新属性的更多信息,请参考:http://www.w3.org/TR/css3-background

3.6.10 多背景图片

CSS3还可以给元素背景添加多个背景图片,下面我们就使用简写属性background来说明,效果见图3-39。

  1. p {
  2. height:150px;
  3. width:348px;
  4. border:2px solid #aaa;
  5.  
  6. margin:20px auto;
  7. font:24px/150px helvetica, arial, sansserif;
  8.  
  9. text-align:center;
  10. background:
  11. url(images/turq_spiral.png) 30px -10px no-repeat,
  12. url(images/pink_spiral.png) 145px 0px no-repeat,
  13. url(images/gray_spiral.png) 140px -30px no-repeat, #ffbd75;
  14. }

enter image description here图3-39 多张图片可以在背景中叠加起来,CSS规则中先列出的图片在上层

在CSS中,我把每张图片的声明都单独放在了一行里,以逗号分隔,以便看清它们的位置、重复的设定值。为了防止图片加载失败时元素背景处于默认的透明状态,这里也在最后一条声明中加上了背景颜色(加粗的值)。要注意的是,代码中先列出的图片显示在上方,或者说,更接近前景。

厂商前缀

为鼓励浏览器厂商尽早采用W3C的CSS3推荐标准,于是就产生了VSP(Vendor Specific Prefixes,厂商前缀)的概念。

有了这些CSS属性的前缀,厂商就可以尝试实现W3C涵盖新CSS属性的工作草案。在迅速实现新属性的同时,还可以声明它们是过渡的、部分实现的,或者实验性的。总之,后果由使用者自负。

就拿W3C推荐的transform属性为例,标准语法是这样的:

transform: skewX(-45deg);

然而,由于这个属性还没有完全定案,为保证在大多数浏览器以及它们的实验性实现中能够使用这个属性,应该针对想要支持的浏览器为该属性添加VSP。每个浏览器只使用各自能理解的属性声明。

  1. -moz-transform:skewX(-45deg); / Firefox /-webkit-transform:skewX(-45deg); / ChromeSafari /-ms-transform:skewX(-45deg); / 微软Internet Explorer /-o-transform:skewX(-45deg); / Opera /transform:skewX(-45deg); / 最后是W3C标准属性 /

VSP的开头是一个连字符,然后是前缀名,接着又是一个连字符,最后是W3C属性名。另外要特别注意,在带前缀的属性声明之后还要声明W3C标准属性,以备将来有浏览器实现完整的不带前缀的属性时派上用场。这里的Safari和Chrome都使用相同的-webkit-前缀,是因为它们都使用Webkit渲染引擎。

以下CSS3属性必须加VPS:

  1. border-image translatelinear-gradient transitionradial-gradient backgroundtransform background-imagetransform-origin

* 针对背景图片或渐变

为了节省篇幅,我不会在每个例子中都写全一套带VPS的属性声明,而只会提醒大家VPS是必要的。随着浏览器的不断更新,有朝一日,VPS可能就用不着了。有关CSS3和VPS的最新信息,可以参考这个网站:http://caniuse.com。如果想实现自动添加VPS,可以使用-prefix-free腻子脚本(polyfill)——参见本书附录。

3.6.11 背景渐变

渐变就是在一定长度内两种或多种颜色之间自然的过渡。CSS3之前,必须依赖Adobe Photoshop等图形处理软件来制作渐变图,再以背景图片方式添加给元素。 而现在,使用CSS就可以创造出各种渐变效果了。

渐变是CSS帮我们生成的背景图片。添加渐变可以使用background-image属性,也可以像后面例子中一样使用简写background属性。

渐变分两种,一种线性渐变,一种放射性渐变。线性渐变从元素的一端延伸到另一端,放射性渐变则从元素内一点向四周发散。

下面来看一个简单的线性渐变的例子,HTML标记如下。

  1. <div class='gradient1'></div>
  2. <div class='gradient2'></div>
  3. <div class='gradient3'></div>

CSS规则如下。

  1. /*为元素盒子添加样式*/
  2. div {
  3. height:150px;
  4. width:200px;
  5. border:1px solid #ccc;
  6. float:left;
  7. margin:16px;
  8. }
  9. /*例1:默认为从上到下*/
  10. .gradient1 {
  11. background:linear-gradient(#e86a43, #fff);
  12. }
  13. /*例2:从左到右*/
  14. .gradient2 {
  15. background:linear-gradient(left, #64d1dd, #fff);
  16. }
  17. /*例3:左上到右下*/
  18. .gradient3 {
  19. background:linear-gradient(-45deg, #e86a43, #fff);
  20. }

enter image description here图3-40 三种简单的渐变效果

图3-40展示了三种简单的渐变效果。例1声明了一种开始属性和一种结束颜色,这两种颜色会按照默认的方向(从下到下)实现平滑过渡。例2起点关键字left,于是渐变方向变成了从左到另一端。例3声明了-45deg(deg是“度”),等于把起点从默认的中上设定到了左上。

1. 渐变点

渐变点就是渐变方向上的点,可以在这些点上设定颜色和不透明度。通过设定下一个渐变点的颜色值,就可以控制渐变的效果。可以添加任意多个渐变点。渐变点的位置一般使用整个渐变宽度的百分比来表示。图3-41展示了使用渐变点后的四种渐变效果。

  1. /*例1:50%处有一个渐变点*/
  2. .gradient1 {
  3. background:linear-gradient(#64d1dd, #fff 50%, #64d1dd);
  4. }
  5. /*例2:20%和80%处有两个渐变点*/
  6. .gradient2 {
  7. background:linear-gradient(#e86a43 20%, #fff 50%, #e86a43 80%);
  8. }
  9. /*例3:25%、50%、75%处有三个渐变点*/
  10. .gradient3 {
  11. background:linear-gradient(#64d1dd, #fff 25%, #64d1dd 50%, #fff 75%, #64d1dd);
  12. }
  13. /*例4:为同一个渐变点设定两种颜色可以得到突变效果*/
  14. .gradient4 {
  15. background:linear-gradient(#e86a43, #fff 25%, #64d1dd 25%, #64d1dd 75%, #fff 75%, #e86a43);
  16. }

enter image description here图3-41 带渐变点的渐变效果

图3-41中的例1在50%处包含一个渐变点,因此渐变效果是从开始颜色到渐变点颜色(白色),然后再从渐变点颜色到结束颜色。注意,开始和结束位置如果没有声明,则默认为0%和100%。

如果不是使用百分比或其他值声明渐变点的位置,则三种颜色会均匀分布于整个渐变,其实际位置是0%、50%和100%。

例2演示了起点和终点不是0%和100%时的情形。此时,在第一个渐变点(20%)之前,是第一个渐变点声明的实色,而在该点之后,则是从该颜色到下一个渐变点颜色的过渡。同样,在最后一个渐变点(80%)之后,该渐变点的颜色会以实色扩展到元素结束。

例3简单展示了相同颜色在几个渐变点之间变来变去的效果。例4展示了在同一个渐变点声明两种不同的颜色,能实现一种突变的效果。

2. 放射性渐变

放射性渐变比线性渐变复杂那么一点点,因为可用的控制点多一些。如果你写过程序,从属性值中的括号就可以看出,渐变属性其实是函数。什么是函数?函数可以接收参数,然后根据这些参数来生成渐变。在创建放射性渐变时,可以使用参数指定形状、位置、尺寸、颜色和不透明度。

下面的每一个例子都设定3种颜色。

  1. .gradient1 {
  2. background: -webkit-radial-gradient(#fff, #64d1dd, #70aa25);
  3. }
  4. .gradient2 {
  5. background: -webkit-radial-gradient(circle, #fff, #64d1dd, #e86a43);
  6. }
  7. .gradient3 {
  8. background: -webkit-radial-gradient(50px 30px, circle, #fff, #64d1dd, #4947ba);
  9. }

这里虽然只声明了-webkit-前缀,但带有其他厂商前缀的属性也是必要的。

enter image description here图3-42 三个三色放射性渐变。第一个是默认的填满图形渐变,第二个是圆形渐变,第三个是指定位置的圆形渐变

在图3-42中,例1展示了默认的渐变形状,即渐变效果会填充元素,这里的元素是矩形。如果元素是正方形,那渐变就是圆形。

例2设定了形状关键字circle,于是渐变的形状变得均匀,并在元素最近的边达到了终点,形成了圆形渐变。而长边剩下的区域则填充了终点的颜色。例3中的位置参数50px 30px把渐变的圆心放到了靠近左上角的位置。

好了,通过以上介绍,你应该已经了解了渐变的原理。本书后面几章在讨论CSS的实际应用时,还会给出如何使用它们的更多示例。

关于这些例子的详细解释,以及如何控制放射性渐变的位置等内容,建议大家看一看我的电子书Visual Stylin' with CSS,2012年由Peachpit Press出版。