I want to set a percentage margin around the element that is 5% of the viewport width when the viewport is smaller and 15% of the viewport width when the viewport is larger.
I can use media queries to toggle the value of the margin like this:
.element { margin: 5%; } @media (min-width: 800px) { .element { margin: 15%; } }
However, I would like a smooth transition between percentages when the window size changes, rather than a sudden jump from one value to another.
I think something like this might work:
@media (min-width: 800px) { .image-grid { margin: 1em calc( (var(--max-margin) - var(--min-margin)) * ((100vw - 800px) / (1920 - 800) + var(--min-margin)) ); } }
This should theoretically smooth changing margin values by setting the margin to a percentage of the change between margins.
For example, when the viewport is small: min-margin [change in margin] * 0
, when the viewport is medium size: min-margin [change in margin] * 0.5
, when the viewport is larger: min-margin [margin change] * 1
But it doesn't actually work because the calc function doesn't return values like 10px / 20px
directly as decimals, like 0.5. Instead, it returns 0.5 pixels. And 15% * 0.5 pixels is unreasonable and will cause the margin to return to the default value of 0.
Maybe I'm going in the wrong direction. Any help would be greatly appreciated.
P粉5117495372023-09-13 17:24:14
Follow up my comment
calc(..)
you must ensure that the terms in the calculation are legal. Be especially meticulous with division and multiplication! %
) will produce results in pixels (px
) for any viewport size unit (vh,vw,vmin,vmax
) and its derived units as well. So your first term (var(--max-margin) - var(--min-margin))
will produce pixel units because of the %## of the size #Convert to pixel result.
((100vw - 800px) / (1920 - 800) var(--min-margin)) also produces a value in pixel units, you are multiplying pixel by pixel .
The
point-slope form of a linear equation y=mx b is perfect for calculating any size relative to the current viewport size. It's like drawing a line on an XY chart, using the low and high point coordinates as (x1,y1) and (x2,y2).
The mathematical formula of point-slope formula: y - y1 = m(x - x1)
In your case
For the low point, we can choose any convenient viewport size and use5% to calculate the margins for that size. I used a viewport width of
400px and got
0.05 * 400 = 20. Now we get the low
(x1,y1) with value (400,20)
15% margins on viewports wider than
800px. Since
0.15 * 800 = 120, the high point
(x2,y2) will be (800,120)
px conversions) and simplify:
5% and
15%, which will require using CSS's
clamp function to get
final result:
Code Snippet Shows the effect of restricted and unrestricted versions (please make the browser full screen and resize to see the difference).
By the way, the slope-intercept form (y = mx b) of the final result is 25vw - 80px.
/* 点斜式 */ .test1 { margin: 0 clamp(5%, 20px + 0.25 * (100vw - 400px), 15%) } .test2 { margin: 0 calc(20px + 0.25 * (100vw - 400px)) } /* 斜截式 */ .test3 { margin: 0 clamp(5%, 25vw - 80px, 15%) } .test4 { margin: 0 calc(25vw - 80px) } /* 仅为视觉效果 */ * { box-sizing: border-box; outline: 1px dashed } body { margin: 0; text-align: center } .test { background-color: Linen }
<h3>点斜式</h3> <div class="test test1">限制</div> <div class="test test2">未限制</div> <h3>斜截式</h3> <div class="test test3">限制</div> <div class="test test4">未限制</div>