Last active
October 21, 2019 07:58
-
-
Save MattMcAdams/069ae113c56b44e9f21113be03c00709 to your computer and use it in GitHub Desktop.
A group of functions to calculate font sizes and line heights based on a typographical scale
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Power function | |
/// @group utility | |
/// @param {number} $base - number to be multiplied | |
/// @param {number (unitless)} $exponents - number of times it should be multiplied | |
/// @return `$base` to the power of `$exponents` | |
@function pow($base, $exponents) { | |
$raised: 1; | |
@for $i from 1 through $exponents { | |
$raised: $raised * $base; | |
} | |
@return $raised; | |
} | |
/// Strips the unit from a number. | |
/// @argument {number} $value | |
/// @return {number (unitless)} | |
/// @example scss | |
/// $dimension: strip-unit(10em); | |
/// | |
/// // Output | |
/// $dimension: 10; | |
@function strip-unit($value) { | |
@return ($value / ($value * 0 + 1)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -------------------------------------------------------------- | |
// TYPOGRAPHY | |
// @requires _functions.scss | |
// -------------------------------------------------------------- | |
$rem-size: 10px !default; // Measurement px | |
$ratio: 1.25 !default; // Number 1.25 = major third | |
$base-txt-size: 18px !default; // Measurement px | |
$base-line-height: 1.6 !default; // Number | |
$txt-size: strip-unit($base-txt-size) / strip-unit($rem-size) + 0rem; //converts raw value to "rem" | |
$line-height: strip-unit($base-txt-size) * $base-line-height / strip-unit($rem-size) + 0rem; // converts raw value to "rem" | |
// ---------------------------------------------------- | |
// TYPE SCALES | |
// ---------------------------------------------------- | |
/// Sets font sizes to a step on the type scale. | |
/// @group typography | |
/// @type map | integers | |
$type-scale: ( | |
large: 5, | |
h1: 4, | |
h2: 3, | |
h3: 2, | |
h4: 1, | |
h5: 0, | |
h6: 0, | |
p: 0, | |
small: -1 | |
) !default; | |
/// Translates string input to numerical step. | |
/// Returns value of input key on the $type-scale map. | |
/// @group typography | |
/// @argument {$input} - key from the $type-scale map. | |
@function type-scale( $input ) { | |
@if not index(map-keys($type-scale), $input) { | |
@error "`#{$input}` is not a valid key in the `$type-scale` map."; | |
} | |
@else { | |
@return map-get( $type-scale, $input ); | |
} | |
} | |
// ---------------------------------------------------- | |
// TYPE SIZE | |
// ---------------------------------------------------- | |
/// Calculates font size based on input scale. | |
/// Returns font size in rem. | |
/// @group typography | |
/// @argument {$input} | |
/// @param {string | number} $input - Key from $type-scale map or number | |
@function type-size($input: null) { | |
$steps: null; | |
@if type-of($input) == string { | |
$steps: type-scale($input); | |
} | |
@else { | |
$steps: $input; | |
} | |
@if type-of($steps) != number { | |
@error "`#{$steps}` is not a valid value for `$steps` in the type-size function. Must be a number."; | |
} | |
@else if $steps == 0 { | |
@return $txt-size; | |
} | |
@else if $steps < 0 { | |
// remove negative from number, division does this for us | |
$steps: $steps * -1; | |
@return strip-unit($txt-size) / pow( $ratio, $steps ) + 0rem; | |
} | |
@else { | |
@return strip-unit($txt-size) * pow( $ratio, $steps ) + 0rem; | |
} | |
} | |
// ---------------------------------------------------- | |
// LINE HEIGHT | |
// ---------------------------------------------------- | |
/// Calculates line height based on input font size | |
/// Returns line height in rem. | |
/// @group typography | |
/// @argument {$input} | |
/// @param {string | number(rem)} $input - Key from $type-scale map or font size in rem. | |
@function line-height( $input: $font-size ) { | |
$size: null; // Declare $size variable | |
$value: strip-unit( $line-height ); // Set starting value for the line height | |
$i: 1; // Init loop | |
@if type-of($input) == string { $size: type-size($input); } // Get the text size if input is a string. The string should be a key on the $font-sizes map. | |
@else { $size: $input; } // If the input is a font size, that will be passed in. | |
$size: strip-unit( $size ); // Strip the unit of the size. | |
@while $value < $size { // Set up loop, check to see if the line height is large enough for the text | |
$value: strip-unit( $line-height ) * $i; // Multiply the line height by an increment of 0.5 | |
$i: $i + 0.5; // Increment the loop each time it is ran | |
} | |
@return $value + 0rem; // Return the line height when it is greater than or euqal to the font size. Add "rem" measurement. | |
} | |
// ---------------------------------------------------- | |
// TYPESETTING | |
// ---------------------------------------------------- | |
/// Set line height and font size for element based on input scale | |
/// Returns line height in rem. | |
/// @group typography | |
/// @argument {$input} | |
/// @param {string} $input - Key from $type-scale map. | |
@mixin type-setting( $input ) { | |
font-size: type-size( $input ); | |
line-height: line-height( $input ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment