调整窗口大小时,如何使边距在两个百分比之间平滑过渡

How to make a margin smoothly transition between two percentages when the window size is adjusted

提问人:Malachi 提问时间:7/25/2023 更新时间:7/26/2023 访问量:36

问:

当视口较小时,我希望元素周围有一个百分比边距,即视口宽度的 5%,当视口较大时,元素周围有 15% 的视口宽度的百分比边距。

我可以使用媒体查询来交换保证金金额,如下所示:

.element {
    margin: 5%;
}

@media (min-width: 800px) {
    .element {
        margin: 15%;
    }
}

但是,我希望它在窗口更改大小时在百分比之间平滑过渡,而不是从一个值捕捉到另一个值。

我认为这样的想法可以工作:

@media (min-width: 800px) {
    .image-grid {
        margin: 1em
            calc(
                (var(--max-margin) - var(--min-margin)) * ((100vw - 800px) / (1920 - 800) +
                    var(--min-margin))
            );
    }
}

从理论上讲,这应该通过将边距值设置为边距之间变化量的百分比来平滑地更改边距值。

例如,当视口较小时:,当视口为中等大小时:,当视口较大时:min-margin + [边距变化] * 1min-margin + [change of margin] * 0min-margin + [change of margin] * 0.5

但事实并非如此,因为 calc 函数不会返回诸如直小数之类的东西,例如。0.5. 相反,它会返回 0.5 px。15% * 0.5 px 是不合逻辑的,会导致边距回到默认值 0。10px / 20px

也许我以错误的方式做这件事。任何帮助将不胜感激。

HTML CSS 边距 视口 viewport-units

评论

1赞 Zain 7/25/2023
您是否尝试过将过渡(过渡:所有 1;
0赞 Malachi 7/25/2023
@Zain 这将使从一个百分比到另一个百分比的切换在一段时间内顺利进行,但在调整视口宽度时不顺利。不过,仍然比捕捉到不同的值要好。
0赞 Rene van der Lende 7/25/2023
在你的方程中,项的结果必须是无单位的。由于元素宽度值产生像素 (),因此失败,因为它根本不接受像 这样的乘法。仅供参考:您使用的是线性方程 y=mx+b 的点斜率形式,在您的情况下转换为:使用无单位点低值 (x1,y1) 和高值 (x2,y2),其中 (x,y) 是(视口宽度,视口宽度处所需的边距)。(var(--max-margin) - var(--min-margin))%pxcalc(..)px * pxmargin = y1 * 1px + (y2 - y1) / (x2 - x1) * (100vw - x1 * 1px)

答:

0赞 Rene van der Lende 7/26/2023 #1

跟进我的评论

  • 在CSS中,您必须确保计算中的术语是合法的。除法和乘法要特别细致!calc(..)
  • 您必须知道,使用大小百分比单位 () 将产生像素 () 结果,任何视口大小单位 () 及其派生也是如此。%pxvh,vw,vmin,vmax

因此,由于大小转换为像素结果,因此您的第一项将产生像素单位。(var(--max-margin) - var(--min-margin))%

由于第二项也以像素单位生成值,因此将像素乘以像素。((100vw - 800px) / (1920 - 800) + var(--min-margin))

人们只是不能用饼干来增加饼干。

线性方程 y=mx+b点斜率形式是计算相对于当前视口大小的任何大小的完美选择。这就像使用低坐标和高坐标 (x1,y1) 和 (x2,y2) 在 XY 图上画一条线。

  • 低点(或坐标)= 低视口大小所需的边距大小 = (x1,y1)
  • 高点(或坐标)= 高视口大小所需的边距大小 = (x2,y2)

点斜率形式的数学运算:y - y1 = m(x - x1)

  • 使用低点 (x1,y1) 和高点 (x2,y2)
  • 用替换方程:y = y1 + (y2 − y1) / (x2 − x1) × (x − x1)

就你而言

对于低点,我们可以选择任何方便的视口大小,并用于计算该大小的余量。我使用了视口宽度,它产生了.现在我们得到值为 (400,20) 的低点 (x1,y1)5%400px0.05 * 400 = 20

高点很容易找到,因为您希望在视口上留出比 更宽的边距。作为高点 (x2,y2) 将是 (800,120)15%800px0.15 * 800 = 120

我们现在要做的就是将值输入到上面的等式中(通过适当的转换)并简化:px

  • margin = 20 * 1px + (120 - 20) / (800 - 400) * (100vw - 400 * 1px)
  • => margin = 20px + 100 / 400 * (100vw - 400px)
  • => margin = 20px + 0.25 * (100vw - 400px)

您希望将最终结果限制在 和 之间,这将需要 CSS 导致最终结果5%15%clamp

  • clamp(5%, 20px + 0.25 * (100vw - 400px), 15%)

代码片段显示了对 clamped 和 unclamped 版本的影响(转到整页并调整浏览器大小以查看差异)。

顺便说一句,最终结果的斜率截距形式y = mx + b) 是 。25vw - 80px

/* point slope form */
.test1 { margin: 0 clamp(5%, 20px + 0.25 * (100vw - 400px), 15%) }
.test2 { margin: 0 calc(20px + 0.25 * (100vw - 400px)) }

/* slope intercept form */
.test3 { margin: 0 clamp(5%, 25vw - 80px, 15%) }
.test4 { margin: 0 calc(25vw - 80px) }

/* just eye-candy */
*      { box-sizing: border-box; outline: 1px dashed }
body   { margin: 0; text-align: center }
.test  { background-color: Linen }
<h3>point slope form</h3>
<div class="test test1">clamped</div>
<div class="test test2">unclampled</div>

<h3>slope intercept form</h3>
<div class="test test3">clamped</div>
<div class="test test4">unclampled</div>