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

7

我有一个精灵(sprite)并在使用它,我想重新使用其中一张图片但大小为原来的一半,所以我尝试使用 background-size:50%;,认为它会将背景大小缩小50%,但出于某种原因,它似乎把图像大小缩小到四分之一:

.test {
  background: url(https://istack.dev59.com/KaIav.webp) 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://istack.dev59.com/KaIav.webp) 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%更大?

是否有一种设置计算方法可以应用于调整精灵大小时使用?

2个回答

7
根据W3C规范

百分比相对于背景定位区域

背景定位区域是基于background-origin属性的border-boxpadding-boxcontent-box之一。在此,您没有明确指定任何值,因此使用其默认值padding-box。该元素没有填充,因此等于content-box
您的图片大小为126 x 112像素,但元素的宽度和高度为56 x 56像素,因此background-size:100%(被推断为100% auto)意味着图像缩小到具有56像素的宽度。现在,为了达到56像素,宽度将按原始大小的44.44%缩小。因此,为了保持纵横比(一个值为auto),图像的高度也会缩小44.44%,即49.78像素(或约50px)。如您所见,计算得出的背景图像尺寸为56 x 50像素(而不是56 x 56像素),因此它无法完全覆盖框。您可以在下面的代码片段中清楚地看到这一点。

.test {
  background: url(https://istack.dev59.com/KaIav.webp) 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>

注意:56像素的宽度包括圆圈右侧的空白区域,因此即使它覆盖了元素的整个宽度,仍然会看到间隙。这是由于图像本身具有空间造成的。

Now when you set background-size: 50% ( = 50% auto), it would mean the max width of the image can be 28px and so it is scaled down by 22.22%. This means the height is also scaled down 22.22%, which is, roughly 25px. This is why you see it as being almost quarter size (but not exactly quarter). This can again be seen visually in the below snippet:

.test {
  background: url(https://istack.dev59.com/KaIav.webp) 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,因此图像相对于容器的左边缘放置,因此出现在图像右侧的白色空间(另外的7.28px)是不可见的,因为盒子不会显示超过其宽度的任何内容。

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


对于未来的读者:对于OP的情况,可能无法去除空格,因为它是精灵的一部分,但如果您的情况不同并且您可以去除空格,则这是最好的选择。
如果右侧的空格被移除并且图像被裁剪到其实际大小(即112 x 112px),那么仅设置background-size: 100% 100%(甚至是100%auto)就足够了。当容器元素的尺寸设置为原始尺寸的一半或四分之一(或任何其他尺寸)时,将自动进行缩放。

.test {
  background: url(https://istack.dev59.com/UaCct.webp) 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>


1
很好的解释,现在我明白为什么它是相对于精灵而不是与新框有关的比率了,谢谢。 - Pete
1
不客气,@Pete。你的提问让我回答起来更容易了,因为虽然我知道如何完成,但是对于你的第二个问题,我需要花费一些时间来计算百分比。 - Harry

4

经过对精灵进行了大量的试验,我得出结论:将整个精灵的宽度除以精灵部分的宽度并乘以100,即可获得x轴背景大小的百分比,对于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://istack.dev59.com/KaIav.webp) 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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接