CSS Backgrounds
撰写时间:2025-03-08
修订时间:2025-03-22
概述
CSS background 在CSS Backgrounds and Borders Module Level 3 中定义,用以指定背景颜色或背景图像,可控制的方面有大小、位置及平铺 (tiled)。
background 所影响到的区域包括盒模型中的主体内容及padding 区域。
div {
width: 100px;
height: 100px;
border: 10px solid gray;
padding: 1em;
background: deepskyblue;
}
父容器中的background 不会被继承,但由于background 属性的默认值为transparent ,因此子标签会透出父容器的背景色。
#container {
width: 100px;
height: 100px;
background: deepskyblue;
display: flex;
justify-content: center;
align-items: center;
}
#child {
width: 50px;
height: 50px;
background: transparent;
border: 1px solid gray;
}
background-color
background-color 用以指定背景颜色。
div {
background-color: #555;
height: 80vh;
margin: 10vh;
aspect-ratio: 1 / 1;
}
要显示背景内容的标签应指定一个初始的尺寸大小。
background-image
background-image 用以指定背景图像。CSS Images Module Level 3 规定了,背景图像可以为图片文件,或者为渐变色。
下面是一张原始大小为256 * 256 的图像。
star.png
将其用作背景图像:
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgray;
width: auto;
height: 100vh;
border: 1px solid orange;
box-sizing: border-box;
}
一般情况下,在使用background-image 指定背景图像时,最好同时使用background-color 同时指定背景颜色。这样做的好处是,如果背景图像有透明通道,则在透明的区域显出背景颜色;如果无法加载背景图像,则显示背景颜色;而如果加载背景图像(没有透明通道)成功,则不会显示背景颜色。
要显示背景图像的div 的尺寸大小,其高度为150px ,比背景图像的高度小;宽度自动铺满整个客户端,一般情况下比背景图像的宽度要大。
修改div 的width 及height 属性值,观察它们的变化。
可以看出,默认情况下,背景图像以原始比例,从div 的左上角开始,从左到右,从上到下平铺排列。但前提条件是div 的尺寸要够宽够高,才能看到相应轴向上的平铺效果。
Filter Effects Module Level 1 规定了,可对img 使用filter 函数。下面通过调用该函数,使背景图像的亮度降低40% 。
div {
background-image: filter(url(/js/esm/three/manual/examples/resources/images/star.png), brightness(60%));
background-color: darkgray;
width: 50vw;
height: 200vh;
border: 1px solid orange;
box-sizing: border-box;
}
继而可以应用到主题颜色切换中:
@media(prefers-color-scheme: dark) {
div {
background-image: filter(url(/js/esm/three/manual/examples/resources/images/star.png), brightness(60%));
}
div > p {
color: rgb(255, 255, 98);
}
}
@media(prefers-color-scheme: light) {
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
}
div > p {
color: #B0A9E9;
}
}
div {
background-color: darkgray;
width: 50vw;
height: 100vh;
border: 1px solid orange;
box-sizing: border-box;
text-align: center;
}
div > p {
margin: 45vh auto;
font-size: 1.5em;
}
Text on top of background image.
在暗黑主题模式中,先将背景图像的亮度降低,再将文本颜色设为一个较亮的颜色值;在高亮主题模式中,背景图像的亮度不变,仅将文本颜色设为一个适合的颜色值。
在操作系统中切换主题颜色,以查看不同的效果。
本例在高亮主题模式中的文本颜色值不大好设置,因为背景图像本身就同时带有高亮部分及亮度稍黑的背景,文本颜色值必须兼顾所有这些颜色。
background-repeat
设置background-repeat 属性值的语法为:
background-repeat = <repeat-style>#
<repeat-style> = repeat-x | repeat-y | [repeat | space | round | no-repeat]{1,2}
repeat-x
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgray;
width: calc(256px * 5);
background-repeat: repeat-x;
height: 100vh;
border: 1px solid orange;
box-sizing: border-box;
}
先将div 的宽度值设置为背景图像宽度值的5 倍,然后再将background-repeat 属性的值设置为repeat-x ,则背景图像只在X 轴上重复,而Y 轴不再重复。
因为div 首要用作容器,本身可无任何内容,因此要显示出其背景图像,需为其高度设定一个合理的初始值。
根据语法表,也可使用下面语法,只在X 轴上进行平铺:
background-repeat: repeat no-repeat;
repeat-y
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgray;
height: calc(256px * 5);
background-repeat: repeat-y;
width: auto;
border: 1px solid orange;
box-sizing: border-box;
}
先将div 的高度值设置为背景图像高度值的5 倍,然后再将background-repeat 属性的值设置为repeat-y ,则背景图像只在Y 轴上重复,而X 轴不再重复。
根据语法表,也可使用下面语法,只在Y 轴上进行平铺:
background-repeat: no-repeat repeat;
repeat-x repeat-y
将background-repeat 的值设置为repeat-x repeat-y ,则在X 轴及Y 轴上均分别进行平铺。
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgray;
background-repeat: repeat-x repeat-y;
width: calc(256px * 2);
height: calc(256px * 2);
border: 1px solid orange;
box-sizing: border-box;
}
根据语法表,也可使用下面语法,同时在X 轴及Y 轴上均进行平铺:
background-repeat: repeat repeat;
或者,简化为:
background-repeat: repeat;
当其值只有一个repeat 时,则同时在X 轴及Y 轴上均进行平铺。
当背景填充区域 (background painting area) 的尺寸不是背景图像尺寸的整数倍时,超出背景填充区域之外的部分,将被裁剪。
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgray;
background-repeat: repeat-x repeat-y;
width: calc(256px * 2.8);
height: calc(256px * 2.2);
border: 1px solid orange;
box-sizing: border-box;
}
space
将background-repeat 的值设置为space ,可在平铺的同时,添加空白间隔。具体为,在X 轴及Y 轴上均分别进行平铺,并且第一个背景图像和最后一个背景图像靠两边对齐;中间的空间,看最多能分配多少个不重叠的背景图像,剩余的空间当作各个背景图像的间隔。
文字表述较晦涩,但一看下面的效果就明白。
:root {
--div-width: calc(256px * 8);
--div-height: calc(256px * 5);
transform: scale(min(calc(100vw / var(--div-width)), calc(100vh / var(--div-height))));
transform-origin: 0 0;
}
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgoldenrod;
background-repeat: space;
width: var(--div-width);
height: var(--div-height);
border: 1px solid orange;
box-sizing: border-box;
}
div 的宽度值为8 张背景图像的宽度值,因需要添加背景图像之间的空格,故最多只能平铺7 张背景图像,多出的空间用以分开相邻的背景图像。在Y 轴上的编排也是同理。
空白间隔的颜色,取自于background-color 所指定的颜色值。上面该值为darkgoldenrod ,即土黄色。
不同于上面的多个例子,本例为使整个图像都完整地显示在客户端中,在:root 最顶层的标签上设置了缩放。使用100vw ,除以水平方向上需放置多少张背景图像的宽度,即为水平方向上的缩放因子;同理,使用100vh ,除以垂直方向上需放置多少张背景图像的高度,即为垂直方向上的缩放因子。从这两个缩放因子中取出最小值作为统一缩放因子。这样无需拉动滚动条即可从全局一下子看到整个效果。
上面--div-width 及--div-height 的值可设为小数点,这样小数点部分将用作空白间隔,整数部分则作为平铺的次数。
:root {
--div-width: calc(256px * 4.8);
--div-height: calc(256px * 5.2);
transform: scale(min(calc(100vw / var(--div-width)), calc(100vh / var(--div-height))));
transform-origin: 0 0;
}
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgray;
background-repeat: space;
width: var(--div-width);
height: var(--div-height);
border: 1px solid orange;
box-sizing: border-box;
}
在水平方向上平铺4 次,在垂直方向上平铺5 次,小数部位值较大的,空白间隔更大。明白了原理,这样的效果更为直观。
round
将background-repeat 的值设置为round ,如果背景填充区域的尺寸不是背景图像尺寸的整数倍,在确保背景填充区域不变的情况下,将背景图像的尺寸进行相应的缩放,再进行平铺。
:root {
--div-width: calc(256px * 4.2);
--div-height: calc(256px * 5);
transform: scale(min(calc(100vw / var(--div-width)), calc(100vh / var(--div-height))));
transform-origin: 0 0;
}
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: darkgray;
background-repeat: round;
width: var(--div-width);
height: var(--div-height);
border: 1px solid orange;
box-sizing: border-box;
}
--div-width 作为背景填充区域的宽度,比4 张背景图像的宽度还多出了256px * 4 * 0.2 的空间,则将每张背景图像的宽度增加0.2px ,再进行水平平铺。
将--div-width 改为calc(256px * 4.5) ,可看到水平方向上的变形比较明显。再改为calc(256px * 4.6) ,为消除水平方向上已经较为明显的变形,则改为在水平方向上平铺5 次。
因此其决定平铺次数的规律是,对小数部分五舍六入 。
repeat 与round 的区别是:repeat 不会改变背景图像的尺寸大小;而round 可能会改变背景图像的尺寸大小,并在保证背景图像不过度变形的前提下,适当修改平铺次数。
repeat
将background-repeat 的值设置为repeat ,则在X 轴及Y 轴上重复平铺。
:root {
--div-width: calc(256px * 5);
--div-height: calc(256px * 5);
transform: scale(min(calc(100vw / var(--div-width)), calc(100vh / var(--div-height))));
transform-origin: 0 0;
}
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: #2F3F4F;
background-repeat: repeat;
width: var(--div-width);
height: var(--div-height);
border: 1px solid orange;
box-sizing: border-box;
}
no-repeat
将background-repeat 的值设置为no-repeat ,则在X 轴及Y 轴上,均不重复平铺。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
transform: scale(min(calc(100vw / var(--div-width)), calc(100vh / var(--div-height))));
transform-origin: 0 0;
}
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: #2F3F4F;
background-repeat: no-repeat;
width: var(--div-width);
height: var(--div-height);
border: 1px solid orange;
box-sizing: border-box;
}
使用repeat指定单轴重复平铺
在相应轴向上将background-repeat 的值设置为repeat ,另一轴向上设置为no-repeat 。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
transform: scale(min(calc(100vw / var(--div-width)), calc(100vh / var(--div-height))));
transform-origin: 0 0;
}
div {
background-image: url(/js/esm/three/manual/examples/resources/images/star.png);
background-color: #2F3F4F;
background-repeat: no-repeat repeat;
width: var(--div-width);
height: var(--div-height);
border: 1px solid orange;
box-sizing: border-box;
}
background-position
background-position 将背景图像放在背景填充区域指定的位置。
注:从本节开始,已将一些辅助性的CSS 代码移到外部文件,CSS 面板中仅保留相关的内容。
使用命名常量指定位置
在X 轴上设置为left , center , right ,在Y 轴上设置为top , center , bottom 。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
}
div {
background-repeat: no-repeat;
background-position: center top;
}
如果只使用1 个值,且从该值能明确地推导出相应的轴,则根据该值自动选取相应的轴:left 或right 对应于X 轴;top 或bottom 对应于Y 轴。未使用值的轴自动设置为center 。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
}
div {
background-repeat: no-repeat;
background-position: left;
}
如果只使用1 个值,且该值为center ,则在X 轴及Y 轴均设为居中。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
}
div {
background-repeat: no-repeat;
background-position: center;
}
使用有效的CSS值指定位置
这里有效的CSS 值,是指对应于长度 的CSS 值,如50px , 25% , 2em 等。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
}
div {
background-repeat: no-repeat;
background-position: 25% 5em;
}
下面是命名常量与百分比数值的对应转换表:
轴向 0% 50% 100%
X 轴left center right
Y 轴top center bottom
指定偏移值
可在指定位置的值的后面加上一个数值,以表示从该位置向中心偏移特定的数值。该值若为负数,则表示从该处向背景填充区域之外的方向偏移。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
}
div {
background-repeat: no-repeat;
background-position: left 50px top -50px;
}
多个数值的含义
数值数量 对应 默认构全
X轴 Y轴 X轴 Y轴
位置 偏移 位置 偏移 位置 偏移 位置 偏移
1 value value 0 center 0
2 value1 value2 value1 0 value2 0
3 命名常量1 value 命名常量2 命名常量1 value 命名常量2 0
命名常量1 命名常量2 value 命名常量1 0 命名常量2 value
4 命名常量1 value1 命名常量2 value2
当数值数量为3 或4 个时,必须使用命名常量来代表相应轴向上特定位置的值。
:root {
--div-width: calc(256px * 2);
--div-height: calc(256px * 2);
}
div {
background-repeat: no-repeat;
background-position: left top 25%;
}
同时指定位置与平铺
当同时指定位置与平铺时,先确定位置,再进行平铺。
:root {
--div-width: calc(256px * 8.9);
--div-height: calc(256px * 5);
}
div {
background-repeat: space no-repeat;
background-position: center 25%;
}
body > div {
background-color: hsl(from rgb(40, 111, 68) h s calc( l * 0.7) / 0.3);
}
background-origin
:root {
--div-width: calc(256px * 8);
--div-height: calc(256px * 5);
}
div {
background-origin: content-box;
background-repeat: no-repeat;
background-position: left top;
}
body > div {
border: 100px solid hsla(180, 50%, 50%, 0.8);
padding: 100px;
background-color: hsla(120, 50%, 50%, 0.5);
}
div > div {
width: 100%;
height: 100%;
background-image: unset;
background-color: rgb(0, 0, 255, 0.3);
}
此例中,border 及padding 的值均设为100px ,从而出现了3 个方框。其中,border 方框为青色,padding 方框为绿色,content 方框为蓝色。这3 个方框的区域,统称为背景定位区域 (background positioning area )。
通过background-origin 来指定background-position 的值相对于哪个方框。
上面代码指定,background-position 的值,从content 方框的左上角起算。
background-origin 的值,从里到外,可分别指定为content-box , padding-box 及border-box ,共3 种。其中,padding-box 是默认值。
将background-origin 的值修改为另外两个值,可看到相应效果。
但无论从哪个方框起算,在平铺时,都会自动铺满整个div 。
:root {
--div-width: calc(256px * 20);
--div-height: calc(256px * 8);
}
div {
background-origin: content-box;
background-repeat: repeat;
background-position: center;
}
body > div {
border: 100px solid hsla(180, 50%, 50%, 0.8);
padding: 100px;
background-color: hsla(120, 50%, 50%, 0.5);
}
div > div {
width: 100%;
height: 100%;
background-image: unset;
background-color: rgb(0, 0, 255, 0.3);
}
background-size
background-size 属性用以控制在背景定位区域内,每张背景图像的尺寸大小。
contain
当background-size 的值为contain 时,则在背景定位区域内按比例缩放每张背景图像的尺寸大小,使所有平铺的背景图像作为整体,在水平方向或垂直方向上正好顶住背景定位区域的边框线。
:root {
--div-width: calc(256px * 27);
--div-height: calc(256px * 5);
}
div {
background-size: contain;
background-origin: padding-box;
background-repeat: space no-repeat;
background-position: center;
}
body > div {
border: 100px solid hsla(180, 50%, 50%, 0.5);
padding: 100px;
background-color: hsla(120, 50%, 50%, 0.5);
}
div > div {
width: 100%;
height: 100%;
background-image: unset;
background-color: rgb(0, 0, 255, 0.3);
}
也即,将背景图像的大小按比例缩放,以限制在背景定位区域内。由于当background-repeat 的值为space 时,要求头尾两张图像必须顶边,因此这两者可以很好地配合使用。
box-shadow
div {
width: 100px;
height: 100px;
border: 1px solid orange;
background-color: #444;
margin: 1em auto;
box-shadow:
rgba(0, 0, 0, 0.3) /* color */
10px 10px 15px 2px /* x-offset, y-offset, blur, spread */
inset; /* outer or inner */
}
spread 的值用以伸缩(负数表示缩小)阴影。若x-offset 或y-offset 的值不为0 时,则在相应的方向伸缩。当x-offset 及y-offset 的值均为0 时,依圆心全向伸缩。
div {
width: 200px;
aspect-ratio: 2 / 1;
border: 1px solid orange;
border-radius: 0.5em;
background-color: #444;
margin: 2em auto;
box-shadow:
rgba(0, 0, 0, 0.3) /* color */
0px 0px 20px 15px /* x-offset, y-offset, blur, spread */
;
}