Skip to content

Instantly share code, notes, and snippets.

@MattMcAdams
Last active October 21, 2019 07:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MattMcAdams/069ae113c56b44e9f21113be03c00709 to your computer and use it in GitHub Desktop.
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
/// 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));
}
// --------------------------------------------------------------
// 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