如何计算背景大小百分比?

How is background-size percentage calculated?

我有一个正在使用的 sprite,我想重复使用 sprite 中的其中一张图像,但大小只有一半,所以我想如果我只使用 background-size:50%;,它会将背景大小调整 50 %,但由于某种原因它似乎缩小了四分之一:

.test {
  background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
  width: 112px;
  height: 112px;
  border: 1px solid red;
}

.test.half-size {
  width: 56px;
  height: 56px;
  background-size: 50%;
}
<div class="test"></div>
<div class="test half-size"></div>

现在我可以通过将背景大小设置为 113% 来解决此问题:

.test {
  background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
  width: 112px;
  height: 112px;
  border: 1px solid red;
}

.test.half-size {
  width: 56px;
  height: 56px;
  background-size: 113%;
}
<div class="test"></div>
<div class="test half-size"></div>

但是为什么图片比原图小的时候background-size大于100%呢?

在弄清楚如何调整 sprite 大小时,我可以应用一组计算吗?

经过多次使用精灵我得出的结论是完整精灵的宽度 divided by sprite part width and times it by 100 will give you the x-axis背景大小百分比,然后对 y 轴背景大小的高度执行相同操作。

所以在我的例子中,要获得 x 百分比,它是

(         126px         /         112px        ) * 100 = 112.5% 
  Full width of sprite     width of sprite part

并得到 y 百分比是

(         112px         /         112px        ) * 100 = 100% 
 Full height of sprite     height of sprite part

这意味着 background-size: 112.5% 100% 将适用于具有该精灵的任何正方形 div:

.test {
  background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
  width: 112px;
  height: 112px;
  background-size: 112.5% 100%;
  border: 1px solid red;
}

.test.half-size {
  width: 56px;
  height: 56px;
}
.test.random-size {
  width: 90px;
  height: 90px;
}
<div class="test"></div>
<div class="test half-size"></div>
<div class="test random-size"></div>

根据 W3C Specs

A percentage is relative to the background positioning area.

background positioning areaborder-boxpadding-boxcontent-box 之一,基于 background-origin 属性。此处您没有为此明确指定任何值,因此使用其默认值 padding-box。此元素没有填充,因此等于 content-box.


您的图像是 126 x 112 像素,但元素的宽度和高度是 56 x 56 像素,因此 background-size: 100%(推断为 100% auto)意味着图像被缩小到它的宽度为 56px。现在达到 56px,宽度缩小了图像原始尺寸的 44.44%。因此,为了保持宽高比(因为一个值为自动),高度[=98=图片的]也缩小至44.44%,即49.78px(或50px约).如您所见,计算出的背景图像的尺寸为 56px x 50px(而不是 56px x 56px),因此它没有完全覆盖盒子。您可以在下面的代码片段中清楚地看到这一点。

.test {
  background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
  width: 56px;
  height: 56px;
  border: 1px solid red;
  background-size: 56px 50px; /* see how this is same as 100% or 100% auto */
}

.test.t2 {
  width: 56px;
  height: 56px;
  background-size: 100%;
}

.test.t3 {
  width: 56px;
  height: 56px;
  background-size: 100% auto;
}
<div class="test"></div>
<div class="test t2"></div>
<div class="test t3"></div>

注意: 56px 宽度包括圆圈右侧的白色-spaces,因此即使它覆盖了元素的整个宽度,你仍然会看到一个间隙。这是由于图像本身具有 space.


现在当你设置background-size: 50% ( = 50% auto) 时,这意味着图像的最大宽度可以是28px,因此它被缩小了22.22%。这意味着高度也缩小了 22.22%,即大约 25px。这就是为什么您将其视为 几乎 四分之一大小(但不完全是四分之一)。这可以在下面的代码片段中再次直观地看到:

.test {
  background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
  width: 56px;
  height: 56px;
  border: 1px solid red;
  background-size: 28px 25px; /* again see how they are same */
}

.test.t2 {
  width: 56px;
  height: 56px;
  background-size: 50%;
}

.test.t3 {
  width: 56px;
  height: 56px;
  background-size: 50% auto;
}
<div class="test"></div>
<div class="test t2"></div>
<div class="test t3"></div>


当我们设置background-size: 113%时,这意味着宽度最大可以是容器宽度的113%,这将是 63.28px,这大约是原始图像宽度的 50%。由于宽度从原始图像缩小了50%它的高度也缩小了相同的量,所以结果值是 56px (它只是元素的高度,所以它垂直覆盖了盒子)。现在,由于您还将 background-position 指定为 left-top,因此图像相对于容器的左边缘放置,因此出现在右侧的白色 space图像的一侧(另一侧 7.28px)是不可见的,因为框不会显示超过其宽度的任何内容。

您已经回答了问题的第二部分,因此我不再重复。


对于未来的读者:对于 OP 的情况,可能无法摆脱白色-spaces 因为它是精灵的一部分但是如果你的情况不同,你可以去掉 spaces 那是最好的。

如果右侧的白色-space被移除并且图像被裁剪为其实际大小(即 112 x 112px),则只需设置 background-size: 100% 100%(甚至 100% auto) 就足够了。当容器元素的尺寸设置为原始尺寸的一半或四分之一(或其他)时,将自动为我们进行缩放。

.test {
  background: url(https://i.stack.imgur.com/UaCct.png) left top no-repeat;
  width: 112px;
  height: 112px;
  background-size: 100% 100%;
  border: 1px solid red;
}

.test.half-size {
  width: 56px;
  height: 56px;
}

.test.quarter-size {
  width: 28px;
  height: 28px;
}
<div class="test"></div>
<div class="test half-size"></div>
<div class="test quarter-size"></div>