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.
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
Since the second 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))
Cookies cannot be multiplied by cookies.also produces a value in pixel units, you are multiplying pixel by pixel .
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).
Low point (or coordinate) = required margin size at low viewport size =- (x1,y1)
High point (or coordinate) = required margin size at high viewport size =- (x2,y2)
The mathematical formula of point-slope formula: y - y1 = m(x - x1)
Use low- (x1,y1) and high (x2,y2)
Use the substituted equation: - y = y1 (y2 − y1) / (x2 − x1) × (x − x1)
In your case
For the low point, we can choose any convenient viewport size and use5%
The high point is easy to find because you wantto calculate the margins for that size. I used a viewport width of
400pxand got
0.05 * 400 = 20. Now we get the low
(x1,y1) with value (400,20)15%
We now simply enter the values into the above equation (with appropriatemargins 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
clampfunction 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
.