3.6 背景
本章的主题是定位元素,关于定位元素,最后要讲的一个主题是背景。背景支持为元素添加背景颜色和背景图片。要是你使用过Adobe Photoshop或Adobe Fireworks的话,一定知道图层这个概念。CSS里也一样,每个元素盒子都可以想象成由两个图层组成。元素的前景层包含内容(如文本或图片)和边框,元素的背景层可以用实色填充(使用background-color
属性),也可以包含任意多个背景图片(使用background-image
属性),背景图片叠加在背景颜色之上。
在CSS3被浏览器实现之前,只能在背景颜色上添加一张背景图片。而现在,我们可以为背景图层添加多张图片(以及CSS3渐变)。为了让大家对元素盒子的图层有更直观的认识,下面我们把本章开头的盒模型示意图改成三维透视图,如图3-31所示。
图3-31 这个盒模型示意图展示了元素的前景和背景层
图中的文字:背景颜色、背景图片、内边距、外边距、边框、屏幕上看到的效果
3.6.1 CSS背景属性
CSS规定以下与背景相关属性。
background-color
background-image
background-repeat
background-position
background-size
background-attachment
background
(简写属性)background-clip
、background-origin
、background-break
(目前尚未得到广泛支持)
这些属性可以让我们控制背景图层的方方面面。下面我们就来一个一个地讲解。
3.6.2 背景颜色
background-color
是背景属性中最简单的,通过它可以设定元素的颜色。然后,元素就会以设定的颜色填充背景图层,如图3-32所示。
body {background-color:#caebff;}
p {/*盒子布局样式*/
font-family:helvetica, arial, sans-serif; font-size:18px;
width:350px; margin:20px auto; padding:10px;
/*这个例子中讨论背景和前景样式*/
background-color:#fff; color:#666; border:4px solid;
}
图3-32 body
的background-color
是蓝绿色,段落的background-color
是白色,前景色color
是灰色,前景色既影响文本,也影响边框
这个例子除了演示怎么给元素添加背景色,还演示了前景色的作用范围,也就是前景色会影响元素的内容和边框。当然,有一个前提条件,就是在使用border
设定边框的样式和宽度,而没有设定边框颜色(或者没有使用border-color
单独设定边框颜色)的情况下,边框会使用color
属性设定的字体颜色。默认颜色是黑色。如果你想让边框的颜色有别于文本,就需要单独设定。
3.6.3 背景图片
图3-33是一张包含圆形图案的图片,本节我们就它来示范background-image
和background-repeat
属性。
图3-33 为包含圆形图案的图片添加了边框,圆形四周有空白
接下来,我们通过background-image
属性把这张包含圆形图案的图片放到元素的背景层上,结果如图3-34所示。
- p {
- font-size:28px;
- font-family:helvetica, arial, sans-serif;
- width:345px;
- height:110px;
- margin:20px auto;
- padding:10px;
- color:#000;
- border:4px solid #aaa;
- background-color:#fff;
- background-image:url(images/blue_circle.png);
- }
图3-34 比元素小的背景图片会在水平和垂直方向上重复出现,直至填满整个背景空间
由此可见,默认情况下背景图片会以元素左上角为起点,沿水平和垂直方向重复出现,最终填满整个背景区域。正是因为以元素左上角为原点,所以元素盒子底部和右侧的圆形图案都只显示了一部分。要注意的是,指定背景图片来源的方式,与img
标签中的方式不同,要这样:
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所示。
图3-35 4个不同background-repeat
值的效果
这几种重复方式的用法有很多种。比如,repeat-x
和repeat-y
可以用来实现装饰性的边框效果,而no-repeat
则控制背景图片只出现一次。除了背景图片、背景重复之外,另一个相关的控制选项是background-position
,我们放在下一节介绍。
在此之前先提醒大家一句,CSS3还规定另外两个值(但尚未得到浏览器支持),以控制背景图片重复确切的次数,即所有图片都是完整的,不会出现半张图片的现象。
background-repeat:round
:为确保图片不被剪切,通过调整图片大小来适应背景区域。background-repeat:space
,为确保图片不被剪切,通过在图片间添加空白来适应背景区域。
3.6.5 背景位置
用于控制背景位置的background-position
属性,是所有背景属性中最复杂的。background-position
属性有5个关键字值,分别是top
、left
、bottom
、right
和center
,这些关键字中的任意两个组合起来都可以作为该属性的值。比如,top right
表示把图片放在元素的右上角位置,center center
把图片放在元素的中心位置。事实上,这都是很含糊的说法,下面我们就来详细解释。
千万要注意,background-position
属性同时设定元素和图片的原点。原点决定了元素和图片中某一点的水平和垂直坐标。默认情况下,background-position
的原点位于左上角。换句话说,元素的左上角和图片的左上角是对齐的,随后图片向各个方向重复,都是以左上角为起点。图3-35中所示就是默认以左上角为原点的情形。
有了这个基本共识之后,下面我们就在实践中学习background-position
属性,仍以图3-35中的第一种情况为例。第一情况下,background-position
属性的默认值top left
控制着水平和垂直方向重复的起点。那我们看一看,把起点位置改为center center
之后会有什么不一样(结果参见图3-36)。
/*center center的简化写法*/
p#center {background-position:center;}
只给
background-position
设定一个关键字值,则另一个也会取相同的值(比如这里就相当于写了background-position:center cetner
)。
图3-36 background-position:center center
设定图片中心点与元素中心点重合,然后再向各个方向重复
比较修改前后的结果会发现,第二段中的背景图片是以段落的中心点为起点,然后再向水平和垂直方向重复。
好了,换一种思路。这次我们用百分比来设定位置,结果如图3-37所示。
- div {
- height:150px;
- width:250px;
- border:2px solid #aaa;
- margin:20px auto;
- background-image:url(images/turq_spiral_150.png);
- background-repeat:no-repeat;
- background-position:50% 50%;
- }
图3-37 使用background-position
把背景图片居中
我听见有人小声嘀咕:“为什么文本也跟着垂直居中了呢?”哈哈,这是因为我把
line-height
设定成了元素的高度,而行高是在文本行上下平均分配的。此外,我还把text-align
设定为center
,把文本水平居中。这样就让文本跟背景图片一样,在两个方向上都居中了。
通过把background-position
设定为50% 50%
,把background-repeat
设定为no-repeat
,实现了图片在背景区域内居中的效果。
背景位置的值
设定背景位置时可以使用三种值:关键字、百分比、绝对或相对单位的数值。可以使用两个值分别设定水平和垂直位置。
关键字指的顺序不重要,
left bottom
和bottom 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所示的效果。
图3-38 给一个居中的不重复的背景图片应用不同的background-size
值的效果
这个新属性为我们控制背景图片提供了更多可能性。使用这个属性需要注意,别把本来很小的图片拉得太大,那样会导致图片质量失真。
3.6.7 背景粘附
background-attachment
属性控制滚动元素内的背景图片是否随元素滚动而移动。这个属性的默认值是scroll
,即背景图片随元素移动。如果把它的值改为fixed
,那么背景图片不会随元素滚动而移动。
background-attachment:fixed
最常用于给body
元素中心位置添加淡色水印,让水印不随页面滚动而移动。
实现这种效果的CSS规则如下。
body {
background-image:url(images/watermark.png);
background-position:center;
background-color:#fff;
background-repeat:no-repeat;
background-size:contain;
background-attachment:fixed;
}
没错,关于背景图片的规则写起来有点费劲,因为属性名太长了。别担心,使用简写属性background
就可以在一条声明里设置所有值。
3.6.8 简写背景属性
background
属性可以用来设定所有背景相关的值。比如,前面那个background-attachment
的例子使用简写的background
属性,可以写成这样一条规则:
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。
- p {
- height:150px;
- width:348px;
- border:2px solid #aaa;
- margin:20px auto;
- font:24px/150px helvetica, arial, sansserif;
- text-align:center;
- background:
- url(images/turq_spiral.png) 30px -10px no-repeat,
- url(images/pink_spiral.png) 145px 0px no-repeat,
- url(images/gray_spiral.png) 140px -30px no-repeat, #ffbd75;
- }
图3-39 多张图片可以在背景中叠加起来,CSS规则中先列出的图片在上层
在CSS中,我把每张图片的声明都单独放在了一行里,以逗号分隔,以便看清它们的位置、重复的设定值。为了防止图片加载失败时元素背景处于默认的透明状态,这里也在最后一条声明中加上了背景颜色(加粗的值)。要注意的是,代码中先列出的图片显示在上方,或者说,更接近前景。
厂商前缀
为鼓励浏览器厂商尽早采用W3C的CSS3推荐标准,于是就产生了VSP(Vendor Specific Prefixes,厂商前缀)的概念。
有了这些CSS属性的前缀,厂商就可以尝试实现W3C涵盖新CSS属性的工作草案。在迅速实现新属性的同时,还可以声明它们是过渡的、部分实现的,或者实验性的。总之,后果由使用者自负。
就拿W3C推荐的
transform
属性为例,标准语法是这样的:
transform: skewX(-45deg);
然而,由于这个属性还没有完全定案,为保证在大多数浏览器以及它们的实验性实现中能够使用这个属性,应该针对想要支持的浏览器为该属性添加VSP。每个浏览器只使用各自能理解的属性声明。
- -moz-transform:skewX(-45deg); / Firefox /
- -webkit-transform:skewX(-45deg); / Chrome及Safari /
- -ms-transform:skewX(-45deg); / 微软Internet Explorer /
- -o-transform:skewX(-45deg); / Opera /
- transform:skewX(-45deg); / 最后是W3C标准属性 /
VSP的开头是一个连字符,然后是前缀名,接着又是一个连字符,最后是W3C属性名。另外要特别注意,在带前缀的属性声明之后还要声明W3C标准属性,以备将来有浏览器实现完整的不带前缀的属性时派上用场。这里的Safari和Chrome都使用相同的
-webkit-
前缀,是因为它们都使用Webkit渲染引擎。以下CSS3属性必须加VPS:
- border-image translate
- linear-gradient transition
- radial-gradient background
- transform background-image
- transform-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标记如下。
<div class='gradient1'></div>
<div class='gradient2'></div>
<div class='gradient3'></div>
CSS规则如下。
/*为元素盒子添加样式*/
div {
height:150px;
width:200px;
border:1px solid #ccc;
float:left;
margin:16px;
}
/*例1:默认为从上到下*/
.gradient1 {
background:linear-gradient(#e86a43, #fff);
}
/*例2:从左到右*/
.gradient2 {
background:linear-gradient(left, #64d1dd, #fff);
}
/*例3:左上到右下*/
.gradient3 {
background:linear-gradient(-45deg, #e86a43, #fff);
}
图3-40 三种简单的渐变效果
图3-40展示了三种简单的渐变效果。例1声明了一种开始属性和一种结束颜色,这两种颜色会按照默认的方向(从下到下)实现平滑过渡。例2起点关键字left
,于是渐变方向变成了从左到另一端。例3声明了-45deg
(deg是“度”),等于把起点从默认的中上设定到了左上。
1. 渐变点
渐变点就是渐变方向上的点,可以在这些点上设定颜色和不透明度。通过设定下一个渐变点的颜色值,就可以控制渐变的效果。可以添加任意多个渐变点。渐变点的位置一般使用整个渐变宽度的百分比来表示。图3-41展示了使用渐变点后的四种渐变效果。
/*例1:50%处有一个渐变点*/
.gradient1 {
background:linear-gradient(#64d1dd, #fff 50%, #64d1dd);
}
/*例2:20%和80%处有两个渐变点*/
.gradient2 {
background:linear-gradient(#e86a43 20%, #fff 50%, #e86a43 80%);
}
/*例3:25%、50%、75%处有三个渐变点*/
.gradient3 {
background:linear-gradient(#64d1dd, #fff 25%, #64d1dd 50%, #fff 75%, #64d1dd);
}
/*例4:为同一个渐变点设定两种颜色可以得到突变效果*/
.gradient4 {
background:linear-gradient(#e86a43, #fff 25%, #64d1dd 25%, #64d1dd 75%, #fff 75%, #e86a43);
}
图3-41 带渐变点的渐变效果
图3-41中的例1在50%处包含一个渐变点,因此渐变效果是从开始颜色到渐变点颜色(白色),然后再从渐变点颜色到结束颜色。注意,开始和结束位置如果没有声明,则默认为0%和100%。
如果不是使用百分比或其他值声明渐变点的位置,则三种颜色会均匀分布于整个渐变,其实际位置是0%、50%和100%。
例2演示了起点和终点不是0%和100%时的情形。此时,在第一个渐变点(20%)之前,是第一个渐变点声明的实色,而在该点之后,则是从该颜色到下一个渐变点颜色的过渡。同样,在最后一个渐变点(80%)之后,该渐变点的颜色会以实色扩展到元素结束。
例3简单展示了相同颜色在几个渐变点之间变来变去的效果。例4展示了在同一个渐变点声明两种不同的颜色,能实现一种突变的效果。
2. 放射性渐变
放射性渐变比线性渐变复杂那么一点点,因为可用的控制点多一些。如果你写过程序,从属性值中的括号就可以看出,渐变属性其实是函数。什么是函数?函数可以接收参数,然后根据这些参数来生成渐变。在创建放射性渐变时,可以使用参数指定形状、位置、尺寸、颜色和不透明度。
下面的每一个例子都设定3种颜色。
.gradient1 {
background: -webkit-radial-gradient(#fff, #64d1dd, #70aa25);
}
.gradient2 {
background: -webkit-radial-gradient(circle, #fff, #64d1dd, #e86a43);
}
.gradient3 {
background: -webkit-radial-gradient(50px 30px, circle, #fff, #64d1dd, #4947ba);
}
这里虽然只声明了
-webkit-
前缀,但带有其他厂商前缀的属性也是必要的。
图3-42 三个三色放射性渐变。第一个是默认的填满图形渐变,第二个是圆形渐变,第三个是指定位置的圆形渐变
在图3-42中,例1展示了默认的渐变形状,即渐变效果会填充元素,这里的元素是矩形。如果元素是正方形,那渐变就是圆形。
例2设定了形状关键字circle
,于是渐变的形状变得均匀,并在元素最近的边达到了终点,形成了圆形渐变。而长边剩下的区域则填充了终点的颜色。例3中的位置参数50px 30px
把渐变的圆心放到了靠近左上角的位置。
好了,通过以上介绍,你应该已经了解了渐变的原理。本书后面几章在讨论CSS的实际应用时,还会给出如何使用它们的更多示例。
关于这些例子的详细解释,以及如何控制放射性渐变的位置等内容,建议大家看一看我的电子书Visual Stylin' with CSS,2012年由Peachpit Press出版。