在线性渐变上使用背景位置的百分比值 [英] Using percentage values with background-position on a linear-gradient

查看:93
本文介绍了在线性渐变上使用背景位置的百分比值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以使background-position取百分比值?目前,我的按钮仅适用于widthbackground-position的显式值.

Is there any way to make background-position take percentage values? Currently my button only works with an explicit values for width and background-position.

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
}

.button {
  display: flex;
  justify-content: center;
  align-items: center;
  text-decoration: none;
  color: white;
  font-weight: bold;
  width: 350px;
  height: 50px;
  border: 1px solid green;
  transition: background 0.5s;
  background-repeat: no-repeat;
  background-image: linear-gradient(to left, #2484c6, #1995c8 51%, #00bbce), linear-gradient(to right, #2484c6 0%, #1995c8 51%, #00bbce 76%);
}
.button-pixel {
  background-position: -350px 0px, 0px 0px;
}
.button-pixel:hover {
  background-position: 0px 0px, 350px 0px;
}
.button-percentage {
  background-position: -100% 0px, 0px 0px;
}
.button-percentage:hover {
  background-position: 0% 0px, 100% 0px;
}

<a href="#" class="button button-pixel">In Pixel</a>
<a href="#" class="button button-percentage">In Percentage</a>

推荐答案

TL; DR

使用渐变作为背景时,与background-position 一起使用的所有百分比值都是等效的,因此您不会看到任何差异.您需要指定与容器大小不同的background-size:

TL;DR

All the percentage values used with background-position are equivalent when using a gradient as background, so you won't see any difference. You need to specify a background-size different from the container size:

body {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
  min-height:90vh;
}

.button {
  text-decoration: none;
  color: white;
  font-weight: bold;
  width: 350px;
  height: 50px;
  text-align:center;
  transition: background 0.5s;
  background-repeat: no-repeat;
  background-image: 
    linear-gradient(to left, #2484c6, #1995c8 51%, #00bbce), 
    linear-gradient(to right, #2484c6 0%, #1995c8 51%, #00bbce 76%);
  background-size:200% 100%; /*Changed this*/
}
.button-pixel {
  background-position: -350px 0px, 0px 0px;
}
.button-pixel:hover {
  background-position: 0px 0px, 350px 0px;
}
.button-percentage {
  background-position: 100% 0px, 0px 0px;
}
.button-percentage:hover {
  background-position: 0% 0px, 100% 0px;
}

<a href="#" class="button button-pixel">Pixel</a>
<a href="#" class="button button-percentage">Percentage</a>

让我们使用经典图片来解释background-position的工作原理.

Let's use a classic image in order to explain how background-position works.

使用像素值时,无论大小如何,参考点都是图像的左上角.就像将top/left与定位的元素一起使用:

When using pixel values, the reference is the top/left corner of the image, whatever the size is. It's like using top/left with a positioned element:

.b {
  width:200px;
  height:200px;
  background:url(https://picsum.photos/100/100?image=1069) no-repeat;
  border:1px solid;
  background-position:0 0;
  position:relative;
  animation:back 5s infinite linear alternate;
}
.b:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:10px;
  height:10px;
  background:red;
  animation:change 5s infinite linear alternate;
}

@keyframes back{to{background-position:200px 200px;}}
@keyframes change{to{top:200px; left:200px;}}

<div class="b"></div>

使用百分比值时,参考不同于使用像素值时的参考;不再是左上角:

When using percentage values, the reference is different from when you use pixel values; it's no longer the top/left corner:

.b {
  width:200px;
  height:200px;
  background:url(https://picsum.photos/100/100?image=1069) no-repeat;
  border:1px solid;
  background-position:0% 0%;
  position:relative;
  animation:back 3s infinite linear alternate;
}
.b:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:10px;
  height:10px;
  background:red;
  animation:change 3s infinite linear alternate;
}
@keyframes back{to{background-position:100% 100%;}}
@keyframes change{to{top:200px; left:200px;}}

<div class="b"></div>

在这种情况下,我们需要考虑两个参数:容器的大小和图像的大小.这是它如何工作的说明(我用background-position等于30% 30%):

In this case, we need to consider two parameters: the size of the container AND the size of the image. Here is an illustration of how it works (I took a background-position equal to 30% 30%):

首先,我们考虑图像以找到用于放置图像的参考点.考虑到图像的大小(就像用绿线定义的一样),这是位于图像内部 处的点,该点位于左上角30% 30%处.然后,考虑到容器的大小,将该点从顶部/左侧角30% 30%放置在容器内部 中.

First, we consider the image to find the reference point we will use in order to place the image. It's the point inside the image that is positioned at 30% 30% from the top/left corner considering the size of the image (like defined with the green lines). Then, we place that point inside the container at 30% 30% from the top/left corner considering the size of the container.

根据这种逻辑,我们可以清楚地识别出一些琐碎的情况,例如

From this logic, we can clearly identify some trivial cases like

                50% 50%(中间) 100% 100%(右下) 100% 0%(右上方)

                50% 50% (center)                   100% 100% (bottom right)                   100% 0% (top right)

现在很明显,如果图像的大小等于容器的大小,那么仅会由于所有位置相等而什么也不会发生.图像的顶部/左侧已经在容器的顶部/左侧(0%0%),中心已经在容器的中心(50%50%),等等.

Now it's clear that if the size of the image is equal to the size of the container then nothing will happen simply because all the positions are equivalent. The top/left of the image is already at the top/left (0% 0%) of the container, the center is already at the center (50% 50%) etc.

.b {
  width:200px;
  height:200px;
  background:url(https://picsum.photos/200/200?image=1069) no-repeat;
  border:1px solid;
  background-position:0% 0%;
  position:relative;
  animation:back 5s infinite linear alternate;
}
.b:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:10px;
  height:10px;
  background:red;
  animation:change 5s infinite linear alternate;
}
@keyframes back{to{background-position:100% 100%;}}
@keyframes change{to{top:100%; left:100%;}}

<div class="b"></div>

应用于梯度时,上述逻辑是相同的,因为将梯度视为图像,并且默认情况下,如果不指定background-size,则梯度的大小将为其容器的大小,与使用图像时不同

The above logic is the same when applied to gradients since gradients are considered images, and by default, if you don't specify a background-size, a gradient's size will be the size of its container, unlike when using an image.

如果我们引用规范 background-size中,我们可以看到您的问题是如何产生的:

If we refer to the specification of the background-size, we can see how your problem arises:

如果两个值均为auto,则 的固有宽度和/或高度 应使用图像(如果有),缺少尺寸(如果有)的行为 如上所述为自动.如果图像既没有内在的 宽度或固有高度,其大小由包含确定.

If both values are auto then the intrinsic width and/or height of the image should be used, if any, the missing dimension (if any) behaving as auto as described above. If the image has neither an intrinsic width nor an intrinsic height, its size is determined as for contain.

并且:

包含

缩放图像,同时保留其内部长宽比 (如果有),最大尺寸使其宽度和高度 可以放在背景定位区域内.

Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.

还有:

位图图像(例如JPG)总是具有固有尺寸,并且 比例.

A bitmap image (such as JPG) always has intrinsic dimensions and proportions.

CSS <gradient>没有内在尺寸固有比例.

CSS <gradient>s have no intrinsic dimensions or intrinsic proportions.ref

图像始终具有固有值,因此在大多数情况下,图像的大小与容器的大小不同,因此具有百分比单位的background-position会起作用.但是渐变没有内在值,因此渐变的尺寸将等于其容器的大小,带有百分比值的background-position永远不会起作用,除非我们指定与容器尺寸不同的background-size.

An image always has intrinsic values, so in most cases it won't have the same size as its container, so background-position with percentage units will have an effect. But gradients don't have intrinsic values, thus a gradient's dimensions will be equal to the size of its container, and background-position with percentage values will never work unless we specify a background-size different from its container's dimensions.


我们在上面的示例中看到了使用0%100%之间的值时background-size是如何工作的,但是使用负值或大于100%的值呢?逻辑是一样的,但是找到参考点会比较棘手.

We saw in the above examples how background-size works when using values between 0% and 100%, but what about using negative values or a value bigger than 100%? The logic is the same, but finding the reference point will be more tricky.

负值(<0%)

让我们假设要在-50% 0放置背景.在这种情况下,参考点将在图像之外.这是一个示例:

Let's suppose we want to place a background at -50% 0. In this case the reference point will be outside the image. Here is an example:

.b {
  width:200px;
  height:200px;
  border:1px solid;
  background:url(https://picsum.photos/100/100?image=1069) -50% 0/100px 100px no-repeat;
}

<div class="b"></div>

如插图所示,我们首先考虑图像的-50%,即-50px,以便定义参考点(即,从图像左边缘起-50px).然后,考虑容器的大小(距离容器的左边缘100像素),将该点放置在-50%处.然后我们绘制图像,并获得以上结果.图像的只有100px可见.

As we can see in the illustration, we first consider -50% of the image, which is -50px, in order to define our reference point (i.e., -50px from the left edge of the image). Then we place that point at -50% considering the size of the container (-100px from the left edge of the container). Then we draw the image, and we obtain the above result. Only 100px of the image is visible.

我们还可能注意到,当图像的大小小于容器的大小时,负百分比值的行为与负固定值相同(两者都会使图像向左移动).在这种情况下,-50% 0-50px 0相同.

We may also notice that negative percentage values will behave the same as negative fixed values when the size of the image is smaller than the size of the container (both will shift the image to the left). In this case -50% 0 is the same as -50px 0.

.b {
  width:200px;
  height:200px;
  display:inline-block;
  border:1px solid;
  background:url(https://picsum.photos/100/100?image=1069) -50% 0/100px 100px no-repeat;
}
.a{
  background:url(https://picsum.photos/100/100?image=1069) -50px 0/100px 100px no-repeat;
}

<div class="b">
</div>
<div class="b a">
</div>

例如,如果我们将图像尺寸增加到150px 150px,则-50% 0将与-25px 0相同.

If for example we increase the image size to 150px 150px, -50% 0 will be the same as -25px 0.

当我们使尺寸大于容器时,负值将开始将图像向右移动(与正像素值一样),这是合乎逻辑的,因为图像的50%将增加,而容器的50%将保持不变.

When we make the size bigger than the container, negative values will start shifting the image to the right (like with positive pixel values), which is logical since the 50% of the image will increase while the 50% of the container will remain the same.

如果我们考虑前面的插图,这就像增加顶部的绿线,直到其大于底部的绿线.因此,仅标志不足以知道背景图像将如何移动;我们还需要考虑尺寸.

If we consider the previous illustration, it's like increasing the top green line until it's bigger than the bottom one. So the sign only is not enough to know how the background image will be shifted; we need to also consider the size.

.b{
  width:200px;
  height:200px;
  border:1px solid;
  background:url(https://picsum.photos/300/300?image=1069) -50% 0/50px 50px no-repeat;
  animation:change 2s linear infinite alternate; 
}
@keyframes change{
  to {background-size:300px 300px}
}

<div class="b">
</div>

从逻辑上讲,渐变也会发生同样的事情

The same will logically happen for gradients:

.b {
  width:200px;
  height:200px;
  border:1px solid;
  background:linear-gradient(to right,red,blue) -50% 0/50px 150px no-repeat;
  animation:change 2s linear infinite alternate; 
}
@keyframes change{
  to   {background-size:300px 150px}
}

<div class="b">
</div>

大价值(> 100%)

与之前的逻辑相同:如果我们在150% 0处定义背景,则我们将参考点150%从左侧边缘(或从50%从右侧边缘)考虑,然后将其放置在150%位置.容器的左边缘.

Same logic as previously: if we define a background at 150% 0, then we consider our reference point 150% from the left edge (or 50% from the right edge), then we place it 150% from the left edge of the container.

.b {
  width:200px;
  height:200px;
  border:1px solid;
  background:url(https://picsum.photos/100/100?image=1069) 150% 0/100px 100px no-repeat;
}

<div class="b"></div>

在这种情况下,150% 0等同于150px 0,并且如果我们开始增加背景大小,我们将具有与先前演示的相同的行为:

In this case, 150% 0 is equivalent to 150px 0, and if we start increasing the background size we will have the same behavior as previously demonstrated:

.b {
  width:200px;
  height:200px;
  border:1px solid;
  background:url(https://picsum.photos/300/300?image=1069) 150% 0/50px 50px no-repeat;
  animation:change 2s infinite linear alternate;
}
@keyframes change {
  to {background-size:300px 300px}
}

<div class="b"></div>


使用范围[0% 100%]以外的值可以隐藏背景图像,但是如何找到确切的值以完全隐藏图像?

Using values outside the range [0% 100%] allows us to hide the background image, but how do we find the exact values in order to completely hide the image?

让我们考虑以下插图:

我们的图片的宽度为Ws,容器的宽度为Wp,我们需要找到p的值.从图中我们可以得到以下公式:

Our image has a width Ws and the container a width Wp and we need to find the value of p. From the figure we can obtain the following formula:

p * Wp = p * Ws + Ws   <=>   p = Ws/(Wp - Ws)   where p in [0,1]

如果容器大小为200px,图像为100px,则p1,因此100%(我们当然加上了负号,它是-100%).

If the container size is 200px and the image is 100px then p is 1 so 100% (we add of course the negative sign and it's -100%).

如果我们考虑使用background-size代替固定值的百分比值,则可以使它更通用.假设background-sizeS%.那么我们将得到Ws = Wp * s (s in [0,1] and S=s*100%),公式将为

We can make this more generic if we consider percentage values with background-size instead of fixed values. Suppose the background-size is S%. Then we will have Ws = Wp * s (s in [0,1] and S=s*100%), and the formula will be

p = Ws/(Wp - Ws)   <=>   p = s / (1 - s)

加上负号将是p = s / (s - 1).

现在,如果我们想在右侧隐藏图像,则在右侧执行相同的逻辑(我们考虑上图的镜像),但是由于我们始终考虑左侧以找到我们需要的百分比添加100%.

Now if we want to hide the image on the right side, we do the same logic on the right (we consider a mirror of the previous illustration), but since we will always consider the left edge to find the percentage we need to add 100%.

新的百分比p'%100% + p%,公式将是p' = 1 + p --> p' = 1 + s / (1 - s) = 1 / (1 - s).

The new percentage p'% is 100% + p%, and the formula will be p' = 1 + p --> p' = 1 + s / (1 - s) = 1 / (1 - s).

以下是说明上述计算的动画:

Here is an animation to illustrate the above calculation:

.b {
  width:200px;
  height:50px;
  margin:5px;
  border:1px solid;
  background:linear-gradient(to right,red,blue) no-repeat;
  background-size:calc(var(--s) * 100%) 100%;
  animation:change 4s linear infinite alternate;
}
@keyframes  change{
   from { /*Hide on the left*/
     background-position:calc(var(--s)/(var(--s) - 1) * 100%)
   }
   to { /*Hide on the right*/
     background-position:calc(1/(1 - var(--s)) * 100%)
   }
}

<div class="b" style="--s:0.5">
</div>
<div class="b" style="--s:0.8">
</div>
<div class="b" style="--s:2">
</div>

让我们计算一些值:

s=0.5时,我们的background-size等于50%,并且百分比值将从-100%200%.在这种情况下,我们从负值开始,以正值结束,因为图像尺寸小于容器尺寸.如果考虑最后一种情况(s=2),则background-size等于200%,并且百分比值将从200%-100%.我们以一个正值开始,以一个负值结束,因为图片的大小大于容器的大小.

When s=0.5, we have a background-size equal to 50%, and the percentage values will be from -100% to 200%. In this case, we started with a negative value and ended with a positive one because the size of the image is smaller than the size of the container. If we consider the last case (s=2) the background-size is equal to 200%, and the percentage values will be from 200% to -100%. We started with a positive value and ended with a negative one because the size of the image is bigger than the size of the container.

这证实了我们之前所说的:将图像向左移动时,如果尺寸较小,则需要负值;但是,如果尺寸较大(右侧相同),则需要正值.

This confirms what we said previously: to shift an image to the left we need negative values if the size is small, but we need positive values if the size is big (same thing for the right).


让我们定义一种基于像素值计算百分比值的方法,反之亦然(即在两者之间转换的公式).为此,我们只需要考虑参考点即可.

Let's define a way to calculate percentage values based on pixel values, or vice versa (i.e. the formula to convert between both). To do this we simply need to consider the reference points.

使用像素值时,我们将考虑蓝线,并得到background-position:X Y.

When using pixel values, we will consider the blue lines and we will have background-position:X Y.

使用百分比值时,我们将考虑绿线,并得到background-position:Px Py.

When using percentage values, we will consider the green lines and we will have background-position:Px Py.

公式如下:Y + Py * Ws = Py * Wp其中Ws是图像的宽度,而Wp是容器的宽度(考虑高度的X轴公式相同).

The formula will be like follow : Y + Py * Ws = Py * Wp where Ws is the width of the image and Wp is the width of the container (same formula for the X axis considering height).

我们将有Y = Py * (Wp - Ws).根据该公式,我们可以验证两点,如前所述:

We will have Y = Py * (Wp - Ws). From this formula we can validate two points as explained previously:

  • Wp = Ws时,该公式不再有效,它确认当图像的大小与容器相同时,百分比值无效.因此像素值和百分比值之间没有关系.
  • YPyWp > Ws时将具有相同的符号,在Wp < Ws时将具有相反的符号.这证实了百分比值的行为取决于图像的大小.
  • When Wp = Ws, the formula is no longer valid, which confirms that percentage values have no effect when the size of the image is the same as the container; thus there is no relation between pixel and percentage values.
  • Y and Py will have the same sign when Wp > Ws and will have opposite sign when Wp < Ws. This confirms that percentage value behave differently depending the size of the image.

如果我们考虑background-size的百分比值,我们也可以用不同的方式表达公式.我们将有Y = Py * Wp * (1-s).

We can also express the formula differently if we consider percentage value of background-size. We will have Y = Py * Wp * (1-s).

以下是说明上述计算的动画:

Here is an animation to illustrate the above calculation:

.b {
  width:200px;
  height:50px;
  margin:5px;
  border:1px solid;
  background:linear-gradient(to right,red,blue) no-repeat;
  background-size:calc(var(--s) * 100%) 100%;
  animation:percentage 2s linear infinite alternate;
}
.box.a {
  animation-name:pixel; 
}
@keyframes  percentage{
   from { background-position:-50%;}
   to { background-position:150%;}
}
@keyframes  pixel{
   from { background-position:calc(-0.5 * 200px * (1 - var(--s))) }
   to {  background-position:calc(1.5 * 200px * (1 - var(--s)));}
}

<div class="b" style="--s:0.5">
</div>
<div class="b a" style="--s:0.5">
</div>

<div class="b" style="--s:2">
</div>
<div class="b a" style="--s:2">
</div>


在上述计算中,我们始终考虑图像和容器的左上角,以便将我们的逻辑应用于像素值或百分比值.可以通过向background-position添加更多值来更改此引用.

In the above calculations, we always considered the top/left corner of the image and the container in order to apply our logic either for pixel values or percentage values. This reference can be changed by adding more values to background-position.

默认情况下,background-position: X Y等效于background-position: left X top Y(leftXtopY的位置).通过调整top和/或left,我们可以更改参考和图像放置方式.以下是一些示例:

By default background-position: X Y is equivalent to background-position: left X top Y (position at X from the left and at Y from the top). By adjusting top and/or left we change the reference and how the image is placed. Here are some examples:

.b {
  width:150px;
  height:150px;
  display:inline-block;
  background:url(https://picsum.photos/70/70?image=1069) no-repeat;
  border:1px solid;
  position:relative;
}

body {
 margin:0;
}

<div class="b"></div>
<div class="b" style="background-position:left 0 bottom 0"></div>
<div class="b" style="background-position:right 0 bottom 0"></div>
<div class="b" style="background-position:right 0 top 0"></div>


<div class="b" style="background-position:right 10% top 30%"></div>
<div class="b" style="background-position:right 10% bottom 30%"></div>
<div class="b" style="background-position:right 10px top 20px"></div>
<div class="b" style="background-position:left 50% bottom 20px"></div>

很明显,对于X值,我们只能使用leftright(水平位置),对于Y值,我们只能使用bottomtop(垂直位置) ).通过所有不同的组合,我们可以在逻辑上获得4个不同的角.

It's clear that for the X value we can only use left and right (the horizontal position) and with the Y value we can only use bottom and top (the vertical position). With all the different combinations we can logically obtain the 4 different corners.

此功能对于优化某些计算也很有用.在<特殊情况> 部分的示例中,我们进行了第一个计算以将图像隐藏在左侧,然后进行另一个计算以将其隐藏在右侧.如果我们考虑更改参考,我们只需要进行一次计算即可.我们采用左侧使用的公式,而右侧使用相同的公式.

This feature is also useful in order to optimize some calculation. In the example of the special cases section, we did a first calculation to hide the image on the left then another one to hide it on the right. If we consider changing the reference we only need to do one calculation. We take the formula used for the left side and we use the same on the right side.

这是新版本:

.b {
  width:200px;
  height:50px;
  margin:5px;
  border:1px solid;
  background:linear-gradient(to right,red,blue) no-repeat;
  background-size:calc(var(--s) * 100%) 100%;
  animation:change 4s linear infinite alternate;
}
@keyframes  change{
   from { 
     background-position:left  calc(var(--s)/(var(--s) - 1) * 100%) top 0
   }
   to { 
     background-position:right calc(var(--s)/(var(--s) - 1) * 100%) top 0
   }
}

<div class="b" style="--s:0.5">
</div>
<div class="b" style="--s:0.8">
</div>
<div class="b" style="--s:2">
</div>

对于s=0.5,我们将不再从-100%200%进行动画处理,而是从left -100%right -100%进行动画处理.

For s=0.5 we will no more animate from -100% to 200% BUT it will be from left -100% to right -100%.

这是另一个使用像素值的示例,从中我们可以清楚地看到更改参考值时如何轻松地进行计算:

Here is another example using pixel values where we can clearly see how easy is to deal with the calculation when changing the reference:

.b {
  width:200px;
  height:200px;
  background:url(https://picsum.photos/100/100?image=1069) no-repeat;
  border:1px solid;
  background-repeat:no-repeat;
  animation:change 2s infinite linear;
}


@keyframes change{
  0%{background-position:left 20px top 20px;}
  25%{background-position:right 20px top 20px;}
  50%{background-position:right 20px bottom 20px;}
  75%{background-position:left 20px bottom 20px;}
  100%{background-position:left 20px top 20px;}
}

<div class="b"></div>

通过保持相同的引用来实现相同的动画将非常棘手.因此,如果我们想进行对称动画制作,则可以通过更改参考在一侧进行逻辑处理,而在另一侧使用相同的逻辑处理.

It would be tricky to achieve the same animation by keeping the same reference. So if we want to do a symmetrical animation we do our logic on one side and use the same on the other side by changing the reference.


在CSS3中,我们可以使用calc()来进行一些涉及不同单位的复杂计算.例如,我们可以编写width:calc(100px + 20% + 12em),浏览器将考虑每个单元的工作方式来计算计算值,并以像素值结尾(在这种情况下).

In CSS3 we can use calc() in order to do some complex calculation that involves different units. For example, we can write width:calc(100px + 20% + 12em) and the browser will calculate the computed value considering how each unit works and we will end with a pixel value (for this case).

background-position呢?如果我们写calc(50% + 50px),它将被评估为百分比值还是像素值?像素值会转换为百分比还是相反?

What about background-position? If we write calc(50% + 50px), will this be evaluated to a percentage value or a pixel value? will the pixel value be converted to percentage or the opposite?

结果不会转换为像素值或百分比值,而是将两者一起使用!在calc()中混合百分比和像素值时,background-position具有特殊的行为,其逻辑如下:

The result will not be converted to a pixel value or a percentage value, but rather both will be used together! background-position has a special behavior when mixing percentage and pixel values inside calc() and the logic is as follows:

  1. 我们首先通过应用与百分比值相关的所有逻辑,使用百分比值来定位图像.
  2. 我们将(1)的位置作为参考,并通过应用与像素值有关的所有逻辑,使用像素值再次定位图像.

calc(50% + 50px)的意思是:将图片居中,然后将其向左移动50px.

So calc(50% + 50px) means: center the image, then shift it by 50px to the left.

此功能可以简化很多计算.这是一个示例:

This feature can simplify a lot of calculation. Here is an example:

.b {
  width:200px;
  height:200px;
  display:inline-block;
  border:1px solid;
  background-image:
    linear-gradient(red,red),
    linear-gradient(red,red),
    linear-gradient(red,red),
    linear-gradient(red,red);
 background-size:20px 20px;
 background-position:
    calc(50% + 20px) 50%,
    calc(50% - 20px) 50%,
    50% calc(50% - 20px),
    50% calc(50% + 20px);
 background-repeat:no-repeat;
 transition:0.5s;
}
.b:hover {
  background-position:50%;
}

<div class="b"></div>
<div class="b" style="width:100px;height:100px;"></div>

要找到正确的百分比或像素值来放置4个红色正方形(如上所述)会很麻烦,但是通过使用calc()混合这两个元素很容易.

It would be tedious to find the correct percentage or pixel values to place the 4 red squares like above, but by mixing both using calc() it is pretty easy.

现在,让我们假设我们有这样的东西:calc(10% + 20px + 30% + -10px + 10% + 20px).浏览器将如何处理?

Now, let's suppose we have something like this: calc(10% + 20px + 30% + -10px + 10% + 20px). How will the browser handle this?

在这种情况下,浏览器将首先评估每个单元以获得简化形式calc(X% + Ypx),然后应用上述逻辑来定位图像.

In such case, the browser will first evaluate each unit to obtain the simplified form calc(X% + Ypx) then apply the above logic to position the image.

calc(10% + 20px + 30% + -10px + 10% + 20px) 
calc((10% + 30% + 10%) + (20px + -10px +20px)) 
calc(50% + 30px)

.box {
  display:inline-block;
  width:200px;
  height:200px;
  background-image:url(https://picsum.photos/100/100?image=1069);
  border:1px solid;
  background-position:calc(10% + 20px + 30% + -10px + 10% + 20px) 0;
  background-repeat:no-repeat;
}
.alt {
  background-position:calc(50% + 30px) 0;
}
 

<div class="box"></div>
<div class="box alt"></div>

无论公式的复杂性如何,浏览器始终会分别评估百分比和像素值.

Whatever the complexity of the formula is, the browser will always evaluate percentage and pixel values separately.


这是另一个重要属性,可用于更改背景图像的位置.此属性依赖于box模型,因此让我们快速提醒一下它是如何工作的:

Here is another important property that can be used to alter the position of background image. This property relies on the box model so lets get a quick reminder about how that works:

每个元素内部都有3个不同的框:border-box,padding-box和content-box. background-origin指定了执行先前所有逻辑时需要考虑的框.

Each element has 3 different boxes inside it: border-box, padding-box and the content-box. background-origin specifies which box we need to consider in order to do all our previous logic.

这是一个不言自明的例子:

Here is a self-explanatory example:

.b {
  display:inline-block;
  width:200px;
  height:200px;
  background:
    url(https://picsum.photos/100/100?image=1069) no-repeat,
    linear-gradient(to right,red,blue) bottom/100% 20% no-repeat;
  border:20px solid rgba(0,0,0,0.1);
  padding:20px;
  box-sizing:border-box;

  background-origin:border-box;
}
.p {
  background-origin:padding-box; /*the default value*/
}
.c {
  background-origin:content-box;
}

<div class="b"></div>
<div class="b p"></div>
<div class="b c"></div>

现在应该清楚的是,当我们没有填充时content-box等同于padding-box,而当我们没有边框时border-box等同于padding-box.

It should be clear now that when we don't have padding content-box is equivalent to padding-box, and when we don't have border border-box is equivalent to padding-box.


如果我们真的需要使图像的大小等于容器的大小,并使用像像素这样的百分比来移动它,我们可以考虑以下想法.

In case we really need to have the size of the image equal to the container size and move it using percentage like pixel we can consider the below ideas.

  • 使用伪元素作为背景层:

.b {
  width:200px;
  height:200px;
  border:1px solid;
  position:relative;
  z-index:0;
  overflow:hidden;
}
.b:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:100%;
  height:100%;
  z-index:-1;
  background:url(https://picsum.photos/200/200?image=1069);
  background-size:100% 100%;
  transition:1s;
}
.b:hover::before {
  transform:translate(100%,100%);
}

<div class="b"></div>

我们应该注意,translate考虑伪元素的大小,但是由于它与容器相同,因此不会有任何问题.我们也可以使用left/top,但是transform会有更好的性能.

We should note that translate consider the size of the pseudo element but since it's the same as the container we won't have any issue. We can also useleft/top but transform will have better performance.

  • 使用background-origin

诀窍是使用填充,将原点限制为内容框,并使其大小大于100%来覆盖填充并使图像填充容器.

The trick is to have padding, restrict the origin to content-box and make the size bigger than 100% to cover the padding and have the image fill the container.

.b {
  width:200px;
  height:200px;
  outline:1px solid;
  padding:0 100px 100px 0;
  box-sizing:border-box;
  z-index:0;
  overflow:hidden;
  background:url(https://picsum.photos/200/200?image=1069) no-repeat;
  background-origin:content-box;
  background-size:200% 200%;
  transition:0.8s;
}

.b:hover {
  background-position:-200% -200%; 
  /* We use [0%,-200%] to cover [0%,100%]*/
}

<div class="b"></div>

在上面,我将填充的大小减半,因此从逻辑上讲,我需要使用background-size中的200%进行纠正.对于background-position,现在可以根据上面的说明轻松找到所需的值.

In the above, I made the padding half the size so logically I need to use 200% in background-size to rectify. For the background-position, it's now easy to find the needed value based on the above explanation.

另一个例子:

.b {
  width:200px;
  height:200px;
  outline:1px solid;
  padding:50px;
  box-sizing:border-box;
  z-index:0;
  overflow:hidden;
  background:url(https://picsum.photos/200/200?image=1069) no-repeat;
  background-origin:content-box;
  background-size:200% 200%;
  background-position:50% 50%;
  transition:0.8s;
}

.b:hover {
  background-position:-150% -150%; 
  /* We use [50%,-150%] to cover [0%,100%]*/
}

<div class="b"></div>


请注意,其他单元,例如emch等,其行为与px相同.它们被称为长度.

Note that other units like em, ch, etc, behave the same as px. They are called lengths.

这篇关于在线性渐变上使用背景位置的百分比值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆