// Stylus RFS mixin // // Automated responsive values for font sizes, paddings, margins and much more // // Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE) // Configuration // Base value $rfs-base-value ?= 1.25rem $rfs-unit ?= rem // Breakpoint at where values start decreasing if screen width is smaller $rfs-breakpoint ?= 1200px $rfs-breakpoint-unit ?= px // Resize values based on screen height and width $rfs-two-dimensional ?= false // Factor of decrease $rfs-factor ?= 10 // Mode. Possibilities: "min-media-query", "max-media-query" $rfs-mode ?= "min-media-query" // Generate enable or disable classes. Possibilities: false, "enable" or "disable" $rfs-class ?= false // 1 rem = $rfs-rem-value px $rfs-rem-value ?= 16 // Safari iframe resize bug: https://github.com/twbs/rfs/issues/14 $rfs-safari-iframe-resize-bug-fix ?= false // Disable RFS by setting $enable-rfs to false $enable-rfs ?= true // Cache $rfs-base-value unit $rfs-base-value-unit = unit($rfs-base-value) // Remove px-unit from $rfs-base-value for calculations if $rfs-base-value-unit == "px" $rfs-base-value = unit($rfs-base-value, "") else if $rfs-base-value-unit == "rem" $rfs-base-value = unit($rfs-base-value * $rfs-rem-value, "") // Cache $rfs-breakpoint unit to prevent multiple calls $rfs-breakpoint-unit-cache = unit($rfs-breakpoint) // Remove unit from $rfs-breakpoint for calculations if $rfs-breakpoint-unit-cache == "px" $rfs-breakpoint = unit($rfs-breakpoint, "") else if $rfs-breakpoint-unit-cache == "rem" or $rfs-breakpoint-unit-cache == "em" $rfs-breakpoint = unit($rfs-breakpoint * $rfs-rem-value, "") if $rfs-breakpoint-unit == px $rfs-mq-value = unit($rfs-breakpoint, px) else $rfs-mq-value = unit($rfs-breakpoint / $rfs-rem-value, $rfs-breakpoint-unit) if $rfs-mode == min-media-query $rfs-mq-property-width = min-width else $rfs-mq-property-width = max-width if $rfs-mode == min-media-query $rfs-mq-property-height = min-height else $rfs-mq-property-height = max-height _rfs-rule() if $rfs-class == "disable" and $rfs-mode == max-media-query &, .disable-rfs &, &.disable-rfs {block} else if $rfs-class == "enable" and $rfs-mode == min-media-query .enable-rfs &, &.enable-rfs {block} else {block} _rfs-media-query-rule() if $rfs-class == "enable" if $rfs-mode == min-media-query {block} +_rfs-media-query() .enable-rfs &, &.enable-rfs {block} else if $rfs-class == disable and $rfs-mode == min-media-query .disable-rfs &, &.disable-rfs {block} +_rfs-media-query() {block} // Internal mixin used to determine which media query needs to be used _rfs-media-query() if $rfs-two-dimensional if $rfs-mode == min-media-query @media ({$rfs-mq-property-width}: $rfs-mq-value) and ({$rfs-mq-property-height}: $rfs-mq-value) {block} else @media ({$rfs-mq-property-width}: $rfs-mq-value), ({$rfs-mq-property-height}: $rfs-mq-value) {block} else @media ({$rfs-mq-property-width}: $rfs-mq-value) {block} // Helper function to get the formatted non-responsive value rfs-value($value) if $value == 0 0 else if type-of($value) != "unit" $value else $unit = unit($value) if $unit == "px" if $rfs-unit == "rem" unit($value / $rfs-rem-value, rem) else unit($value, px) else if $unit == "rem" if $rfs-unit == "rem" unit($value, rem) else unit($value * $rfs-rem-value, px) else $value // Helper function to get the responsive value calculated by RFS rfs-fluid-value($value) if $value == 0 0 else if type-of($value) != "unit" $value else if unit($value) != "px" and unit($value) != "rem" $value else if unit($value) == "rem" $value = unit($value * $rfs-rem-value, "") else $value = unit($value, "") // Only add the media query if the value is greater than the minimum value if abs($value) <= $rfs-base-value or !$enable-rfs if $rfs-unit == "rem" unit($value / $rfs-rem-value, rem) else unit($value, px) else // Calculate the minimum value $value-min = $rfs-base-value + (abs($value) - $rfs-base-value) / $rfs-factor; // Calculate difference between $value and the minimum value $value-diff = abs($value) - $value-min; // Base value formatting if $rfs-unit == rem $min-width = unit($value-min / $rfs-rem-value, rem) else $min-width = unit($value-min, px) // Use `vmin` if two-dimensional is enabled if $rfs-two-dimensional $variable-unit = vmin else $variable-unit = vw // Calculate the variable width between 0 and $rfs-breakpoint $variable-width = unit(round($value-diff * 100) / $rfs-breakpoint, $variable-unit) // Return the calculated value if $value != abs($value) unquote("calc(-" + $min-width + " - " + $variable-width + ")") else unquote("calc(" + $min-width + " + " + $variable-width + ")") // RFS mixin rfs($values, $property = font-size) $val = '' $fluidVal = '' // Loop over each value and calculate responsive & non-responsive values for $value in $values $val+= ' ' + rfs-value($value) $fluidVal+= ' ' + rfs-fluid-value($value) // Remove first space $val = unquote(slice($val, 1)) $fluidVal = unquote(slice($fluidVal, 1)) // Do not print the media query if responsive & non-responsive values are the same if $val == $fluidVal {$property}: $val else +_rfs-rule() if $rfs-mode == "min-media-query" {$property}: $fluidVal else {$property}: $val if $rfs-safari-iframe-resize-bug-fix and $rfs-mode == "min-media-query" min-width: 0vw +_rfs-media-query-rule() if $rfs-mode == "min-media-query" {$property}: $val else {$property}: $fluidVal rfs-font-size($value) rfs($value) rfs-padding($value, $property = padding) rfs($value, $property) rfs-padding-top($value, $property = padding-top) rfs($value, $property) rfs-padding-right($value, $property = padding-right) rfs($value, $property) rfs-padding-bottom($value, $property = padding-bottom) rfs($value, $property) rfs-padding-left($value, $property = padding-left) rfs($value, $property) rfs-margin($value, $property = margin) rfs($value, $property) rfs-margin-top($value, $property = margin-top) rfs($value, $property) rfs-margin-right($value, $property = margin-right) rfs($value, $property) rfs-margin-bottom($value, $property = margin-bottom) rfs($value, $property) rfs-margin-left($value, $property = margin-left) rfs($value, $property)