现代 CSS

图解CSS:CSS背景(Part3)

特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

前面已经花了两篇的篇幅(《CSS背景:Part1Part2》)介绍完了除background-size之外的所有background子属性的特性以及使用。众所周之,在Web中对于<img>引入的图片,我们可以显式使用widthheightaspect-ratioobject-fit等属性来调整图片尺寸,但对于背景图片,我们只能使用background-size来进行调整。那么background-size是如何决定背景图片尺寸的计算呢?如果你感兴趣的话,这篇文章可以告诉你很多不为人知的答案。

背景图片尺寸

在 CSS 中,可以显式使用 background-size 给背景图片设置尺寸,背景图片可以保有其原有的尺寸,或者拉伸到新的尺寸,或者在保持其原有比例的同时缩放到元素的可用空间的尺寸。它的语法规则如下:

background-size: <bg-size>#
<bg-size> = [ <length-percentage [0,∞]> | auto ]{1,2} | cover | contain

可以按下面三种方式之一来设置背景图片尺寸:

  • 使用 [ <length-percentage [0,∞]> | auto ]{1,2} 给背景图片指定宽高值
  • 使用关键词 cover ,指定背景图像的大小应尽可能小,同时确保两个尺寸都大于或等于容器的相应大小
  • 使用关键词 contain,指定,无论包含框的大小如何,都应缩放背景图像,以使每一边尽可能大,同时不超过容器对应边的长度

当通过宽度和高度来指定背景图像尺寸时,你可以提供一个或两个数值,可以是 <length-percentage>(即 <length><percentage> 值)或 auto

  • 如果仅显式指定一个数值,那么该数值作为背景图片的宽度值,高度则会设定为 auto
  • 如果显式指定两个数值,那么第一个值作为背景图片的宽度值,第二个值作为背景图片的高度值

简单地说,background-size 可以取 <length><percentage>autocovercontain 值,不同的值所代表的含义如下:

  • auto,将会按照背景图片的宽高比自动缩放背景图片
  • <length>,使用长度值指定背景图片的大小,比如 100px2vw30rem
  • <percentage>,使用百分比值指定背景图片的大小,比如 100%50%等。它的计算是相对于背景层的盒子模型的尺寸,盒子模型的大小由 background-origin 来决定;如果 background-attachment 值为 fixed,它将相对于视窗大小来计算(不包括滚动条尺寸)
  • cover,将图像(同时保持其比例)缩放到尽可能小的尺寸以填充容器(即:其高度和宽度都完全覆盖容器),不留空白。如果背景的比例与元素不同,则图像将被垂直或水平裁剪。
  • contain,在不裁剪或拉伸图像的情况下,在其容器内尽可能大地缩放图像。如果容器大于图像,这将导致图像平铺,除非 background-repeat 属性设置为 no-repeat

下面这个示例展示了background-size取不同类型值时所呈现的效果:

背景图片尺寸的计算

background-size属性只有显式指定两个值为 <length> 值时才会按指定的大小渲染,其他几种情况都会涉及到背景图片的计算:

  • 只显式指定了一个<length><percentage>(另一个值是auto
  • 值为<percentage>
  • covercontain

尤其是取值为 covercontain 时,计算相对而言要复杂一点。接下来,我们一起来探讨背景图片是如何计算的。

背景图片尺寸的计算取决于背景图像的内在尺寸(widthhegiht)和内在比例(宽高比:ratio = width : height)。而这些参数又取决于运用于 background-image 属性的值 <image> 类型。

如果 <image> 是一张位图,那这张背景图有自己的原始尺寸,即宽(width)、高(height)以及相应的比例。比如下面这张 1600px x 900px 的JPG图片:

即:

width = 1600px 
height = 900px
ratio = 1600 / 900 = 16:9

相当于:

img[Attributes Style] {
    width: 1600px;
    aspect-ratio: auto 1600 / 900;
    height: 900px;
}

如果 <image> 是一张矢量图,比如 SVG 图,那它就不一定有内在尺寸。如果它有水平和垂直的固有尺寸,它也有固有的比例。如果它没有维度或只有一个维度,那么它可能有也可能没有比例。

如果 <image> 是渐变绘制的(<gradient>),那它不存在内在的尺寸和内在的比例。

如果 <image> 是使用 element() 函数创建的背景图像,那么它的内在尺寸和内在比例是 element() 函数引用的元素的尺寸和宽高比例。

注意,为了让背景图片计算简化,接下来我们主要围绕着位图的类型为例。比如1600_900.jpg

.element {
    background-image: url('1600_900.jpg');
}

该背景图片的内在尺寸和内在比例是:

  • 背景图片的内在宽度:width = 1600px
  • 背景图片的内在高度:height = 900px
  • 背景图片的内在宽高比:ratio = 16 : 9

我们也知道,在 CSS 中任何元素都是一个盒子,他也有自己的宽高和相应的比例,我们这里称之为容器的宽高和比例。比如:

.element {
    width: 400px;
    height: 300px;
}

那么 .element 容器的宽度是 400px,高是 300px,对应的宽高比是 4:3。也可以使用widthheightaspect-ratio属性来决定一个容器的大小:

.element {
    width: 400px;
    aspect-ratio: 4 / 3;
}

或:

.element {
    height: 300px;
    aspect-ratio: 4 / 3;
}

需要注意的是元素的 border-widthpadding 对于盒子大小是有影响的,而且 box-sizing的值也对盒子尺寸计算有一定的影响。接下来的示例以 box-sizingborder-box 方式来计算。

你可能会感到好奇,探讨背景图片尺寸计算,怎么还要和元素的大小和宽高比扯在一起呢?主要是因为,background-size取值covercontain时,背景图片的计算是会将图片的尺寸和元素容器的尺寸结合起来计算的,它们的计算有一套隐形的公式存在。稍后我们会详细聊到这方面。为了避免一些概念或术语的混淆,提前先统一起来。

参数 背景图片 元素容器 计算后的背景图片
宽度 Wimage Wcontainer W‘
高度 Himage Hcontainer H'
宽高比 Rimage Rcontainer R'

百分比 <percentage>

先来看background-size属性取百分比(%)值时,背景图片的尺寸计算。因为它相对来说要简单一点。background-size取百分比值时,它的计算是相对于元素背景区域的尺寸来计算,而且背景区域的尺寸由 background-origin 来决定(默认为内距盒子<padding-box>的尺寸)。比如:

.element {
    width: 400px;
    aspect-ratio: 4 / 3;
    background-image: url('1600_900.jpg');
    background-size: 50% 50%;
    border: 20px solid rgb(120 200 10 / 0.5);
    padding: 20px;
}

background-size取百分比值时,可以显式设置两个值,其中第一个值是相对于 <box> 的宽度计算,第二个则相对于<box>的高度计算。当然也可以显式指定一个值,如果仅指定一个值,那么第二个值则是 auto。这个时候,将会根据auto规则来计算,即 一个为auto,另一个不是auto

如果图像有固有比例,则指定的长度使用指定值,未指定的长度由指定值与固有比例计算。如果图像没有固有比例,则指定的长度使用指定值,未指定的长度使用图像相应的固有长度,若没有固有长度,则使用背景区相应的长度。

.element {
    background-size: 50%;

    /* 等同于 */
    background-size: 50% auto;

    /* 但不等同于 */
  
剩余80%内容付费后可查看
返回顶部