Skip to content

Instantly share code, notes, and snippets.

@maximilliangeorge
Last active March 14, 2024 19:00
Show Gist options
  • Save maximilliangeorge/4134e99a8bc3de96698eef38886eb1a9 to your computer and use it in GitHub Desktop.
Save maximilliangeorge/4134e99a8bc3de96698eef38886eb1a9 to your computer and use it in GitHub Desktop.
SCSS size interpolation
// strip unit utility function
@function strip-unit($n) {
@return math.div($n, ($n * 0 + 1));
}
/**
* @function interpolate
* interpolates the size of an element based on the size of the screen
*
* @param {px} $el-from - the size of the element at the smallest screen size
* @param {px} $el-to - the size of the element at the largest screen size
* @param {px} $screen-from - the smallest screen size
* @param {px} $screen-to - the largest screen size
* @return {calc()} a calc expression that will interpolate the size of the element
*
*/
@function interpolate($el-from, $el-to, $screen-from, $screen-to) {
$el-from-vw: calc(strip-unit($el-from) / strip-unit($screen-from) * 100vw);
$el-to-vw: calc(strip-unit($el-to) / strip-unit($screen-to) * 100vw);
$el-diff-unitless: strip-unit($el-to) - strip-unit($el-from);
$screen-diff-unitless: - base.strip-unit($screen-from - $screen-to);
$scale-px: calc((100vw - $screen-from) / $screen-diff-unitless);
$el-vw: calc($el-from + ($el-diff-unitless * $scale-px));
@return $el-vw;
}
/**
* @function scale-at
* scales the value relative to a viewport
*
* @param {px} $base - a value
* @param {px} $width - the "ideal" screen size
* @return {calc()} a calc expression
*
*/
@function scale-at ($base: 14px, $width: 1440px) {
$x: strip-unit($base);
$y: strip-unit($width);
$z: math.div($x, $y);
$p: $z * 100vw;
$q: calc($z * (100vw - #{$width}));
@return calc($p - ($q * exp(-0.5)));
}
/**
* @function scale-up
* scales the value beyond the viewport
*
* @param {px} $base - a value
* @param {px} $width - the max screen size
* @return {calc()} a calc expression
*
*/
@function scale-up ($base: 14px, $width: 1440px, $decay: 0.5) {
$x: strip-unit($base);
$y: strip-unit($width);
$z: math.div($x, $y);
$p: $z * 100vw;
$q: calc($z * (100vw - $width));
@return calc($p - ($q * (exp($decay) * -1)));
}
// usage
.some-element {
width: interpolate(100px, 200px, 720px, 1440px);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment