Skip to content

Instantly share code, notes, and snippets.

@Undistraction
Created October 14, 2014 22:13
Show Gist options
  • Save Undistraction/019d7fb41a74a8120422 to your computer and use it in GitHub Desktop.
Save Undistraction/019d7fb41a74a8120422 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.4.5)
// Compass (v1.0.1)
// ----
/*! rhythm v0.1.4 – 14.10.2014 */
////
/// @author Pedr Browne (extracted from Compass Vertical Rhythm by Eric M. Suzanne).
/// @group Config
/// @access public
////
/// Default font size for all text in pixels
$rhythm-base-font-size: 16px !default;
/// Distance between text baselines in pixels.
$rhythm-base-line-height: 21px !default;
/// The unit in which to output rhythm values (px | rem | em)
$rhythm-render-unit: rem !default;
/// If you want to allow rythm to lock everything to half rather than whole lines, set this to true.
$rhythm-round-to-nearest-half-line: false !default;
/// Ensure minimum leading above / below text. Number of lines will be increased if necessary.
$rhythm-min-line-leading: 2px !default;
////
/// @author Pedr Browne (extracted from Compass Vertical Rhythm by Eric M. Suzanne).
/// @group Support
/// @access private
////
/// Units supported as rythm units
$rhythm-supported-rhythm-units: 'px' 'rem' 'em';
/// Default font-size for all browsers (don't change)
$rhythm-browser-default-font-size: 16px;
/// Error thrown when a value is invalid
$rhythm-invalid-value-error: "Invalid Value Error";
/// Error thrown when a unit is invalid
$rhythm-invalid-unit-error: "Invalid Unit Error";
/// Check the given `font-size` and `line-height` to make sure they are valid values.
///
/// @param {String} $font-size
/// The font size
///
/// @param {String} $line-height
/// The line-height
///
/// @return {Bool}
/// Were the values valid?
///
@function rhythm-validate($font-size, $line-height, $unit) {
@if unit($font-size) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "$rhythm-base-font-size must resolve to a pixel unit.");
}
@if unit($line-height) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "$rhythm-base-line-height must resolve to a pixel unit.");
}
@if not is-supported-rhythm-unit($unit) {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "$rhythm-render-unit must be `px`, `em` or `rem`.");
}
@return true;
}
/// Calculate a raw distance value based on number of lines and font-size
///
/// @param {Number} $lines (1)
/// The number of lines of distance
///
/// @param {Number} $font-size ($rhythm-base-font-size)
/// The font size to fit into the lines
///
/// @return {Number}
/// The raw distance value
///
@function rhythm-value-for-lines($lines: 1, $font-size: $rhythm-base-font-size) {
$rhythm: rhythm-convert-value($lines * $rhythm-base-line-height, $rhythm-render-unit, $font-size);
// Round pixel values
@if unit($rhythm) == px {
$rhythm: floor($rhythm);
}
@return $rhythm;
}
/// Calculate the minimum multiple of rhythm units needed to contain the font-size.
///
/// @param {String} $font-size
/// The font size.
///
/// @returns {Number}
/// The number of lines needed to house this font size.
///
@function rhythm-lines-for-font-size($font-size) {
$lines: if($rhythm-round-to-nearest-half-line,
ceil(2 * $font-size / $rhythm-base-line-height) / 2,
ceil($font-size / $rhythm-base-line-height));
// If lines are cramped include some extra leading.
@if ($lines * $rhythm-base-line-height - $font-size) < ($rhythm-min-line-leading * 2) {
$lines: $lines + if($rhythm-round-to-nearest-half-line, 0.5, 1);
}
@return $lines;
}
/// Is the `$rhythm-render-unit` in absolute units (px) or not (em, rem)
///
/// @returns {Bool}
/// Does rhythm use relative font-sizing?
///
@function rhythm-relative-font-sizing() {
@return $rhythm-render-unit != px;
}
/// Given a font-size and line-height, make necessary adjustments to these values so that when
/// set on the `html` element the document will default to these values.
///
/// @param {String} $font-size
/// The font size.
///
/// @param {String} $line-height
/// The line-height
///
/// @return {List}
/// The adjusted font size and line-height
///
@function rhythm-process-base-values($font-size, $line-height) {
// Throw error if invalid
$is-valid: rhythm-validate($font-size, $line-height, $rhythm-render-unit);
@if rhythm-relative-font-sizing() {
// Adjust font size if base font-size different from default browser (16px)
$font-size: 100% * ($font-size / $rhythm-browser-default-font-size);
// Use ems instead of rems to avoid Webkit bug. Usage of rems is uneffected as they will use the
// em value of the html element.
$line-height: rhythm-convert-value($line-height, em);
} @else {
// ( Use given font-size )
$line-height: round(line-height);
}
@return ($font-size $line-height);
}
/// Convert any CSS length or percentage value to any another.
///
/// @param {String} $length
/// A css length or percentage value
///
/// @param {String} $to-unit
/// String matching a css unit keyword, e.g. 'em', '%', etc.
///
/// @param {String} $from-context ($rhythm-base-font-size)
/// When converting from relative units, the absolute length (in px) to
/// which $length refers (e.g. for $lengths in em units, would normally be the
/// font-size of the current element).
///
/// @param {String} $to-context ($from-context)
/// For converting to relative units, the absolute length in px to which the
/// output value will refer. Defaults to the same as $from-context, since it is
/// rarely needed.
///
@function rhythm-convert-value(
$from-length,
$to-unit,
$from-context: $rhythm-base-font-size,
$to-context: $from-context
) {
$from-unit: unit($from-length);
// Optimize for cases where `from` and `to` units are accidentally the same.
@if $from-unit == $to-unit { @return $from-length; }
// Context values must be in px so we can determine a conversion ratio for
// relative units.
@if unit($from-context) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "Parameter $from-context must resolve to a value in pixel units.");
}
@if unit($to-context) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "Parameter $to-context must resolve to a value in pixel units.");
}
// Convert input length to pixels
$px-length: $from-length;
@if $from-unit != 'px' {
// Convert relative units using the from-context parameter.
@if $from-unit == 'em' { $px-length: $from-length * $from-context / 1em }
@else if $from-unit == 'rem' { $px-length: $from-length * $rhythm-base-font-size / 1rem }
@else if $from-unit == '%' { $px-length: $from-length * $from-context / 100% }
@else {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "#{$from-unit} unit not supported");
@return $length;
}
}
// Convert length in pixels to the output unit
$output-length: $px-length;
@if $to-unit != 'px' {
// Relative units
@if $to-unit == 'em' { $output-length: $px-length * 1em / $to-context }
@else if $to-unit == 'rem' { $output-length: $px-length * 1rem / $rhythm-base-font-size }
@else if $to-unit == '%' { $output-length: $px-length * 100% / $to-context }
@else {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "#{$to-unit} unit not supported");
}
}
@return $output-length;
}
/// Check if the unit is supported as a value for $rhythm-render-unit.
///
/// @param {Number} $unit
/// The unit.
///
/// @returns {Bool}
/// Was the unit supported?
///
@function is-supported-rhythm-unit($unit) {
@return not not index($rhythm-supported-rhythm-units, $unit);
}
/// Adjust a block to have different line height to maintain the rhythm.
/// `$lines` specifies how many multiples of the baseline rhythm each line of this
/// font should use up. It does not have to be an integer, but it defaults to the
/// smallest integer that is large enough to fit the font.
///
/// @param {String} $lines
/// The number of lines each line of text should take up.
///
/// @param {String} $font-size ($rhythm-base-font-size)
/// The font-size.
///
/// @output
/// The line-height.
///
@mixin rhythm-render-leading($lines, $font-size: $rhythm-base-font-size) {
@include rhythm-render-property(line-height, rhythm-value-for-lines($lines, $font-size));
}
/// Render rhythm values.
///
/// @param {String) $property
/// The property to render
///
/// @param {String} $values
/// The propery values.
///
/// @output
/// The rendered output.
///
@mixin rhythm-render-property($property, $values) {
$output: ();
@each $value in $values {
@if unit($value) == px {
// Ensure all pixel values are rounded to the nearest pixel.
$output: join($output, round($value));
}
@else {
$output: join($output, $value);
}
}
#{$property}: $output;
}
// SUPPORT (GLUE)
// -------------------------------------------------------------------------------------------------
// These items are used in test only
$rhythm-last-error: null;
$rhythm-under-test: false;
$rhythm-error-thrown: false;
/// By default, this function will throw a Sass error, but allows errors to be stopped during testing,
/// with the error saved to `$box-last-error` instead so tests can check it was thrown.
///
/// @param {String} $error
/// The name of the error
///
/// @param {String} $message
/// The error message
///
/// @returns {Map}
/// A map of offsets to be rendered as CSS properties
///
@function rhythm-throw-error($error, $message) {
@if $rhythm-under-test {
@if not $rhythm-error-thrown {
$rhythm-error-thrown: true !global;
$rhythm-last-error: $error !global;
}
} @else {
@error "#{$error} #{$message}";
}
@return null;
}
////
/// @author Pedr Browne (extracted from Compass Vertical Rhythm by Eric M. Suzanne).
/// @group API
/// @access public
////
/// Establish a rhythm throughout the document using a font-size and line-height.
///
/// @param {Number} $font-size ($rhythm-base-font-size)
/// The font-size to use as base
///
/// @output
/// Render html element with `font-size` and `line-height` set.
///
@mixin rhythm-establish($font-size: $rhythm-base-font-size, $line-height: $rhythm-base-line-height) {
$processed-values: rhythm-process-base-values($font-size, $line-height);
// Render HTML element
html {
font-size: nth($processed-values, 1);
line-height: nth($processed-values, 2);
}
}
/// Adjust a block to have a different font size and line height to maintain the
/// rhythm. `$lines` specifies how many multiples of the baseline rhythm each line
/// of this font should use up. It does not have to be an integer, but it
/// defaults to the smallest integer that is large enough to fit the font.
/// Use `$from-context` to adjust from a font-size other than the base font-size.
///
/// @param {String} $font-size
/// The font-size for this block
///
/// @param {Number} $lines
/// The number of rhythm units (lines) each line of text should should fill.
///
/// @param {Number} $from-context
/// The context of the block (when using ems)
///
/// @output
/// Output the calculated `font-size` and `line-height`.
///
@mixin rhythm($font-size, $lines: auto, $from-context: $rhythm-base-font-size) {
$font-size: rhythm-convert-value($font-size, px, $from-context);
@if $lines == auto {
$lines: rhythm-lines-for-font-size($font-size);
}
@include rhythm-render-property(font-size, rhythm-convert-value($font-size, $rhythm-render-unit, $from-context));
@include rhythm-render-leading($lines, $font-size);
}
/// Use a different rhythm for a block by temporarily changing the configuration values
/// '$rhythm-base-font-size' and '$rhythm-base-line-height'. While this will do nothing by itself,
/// it can be combined with `rhythm-establish` to change the global rhythm temporarily, for example
/// at a breakpoint.
///
/// @param {Number} $new-base-font-size
/// The new `base-font-size` to use for the content of this mixin
///
/// @param {Number} $new-base-line-height
/// The new `base-line-height` to use for the content of this mixin
///
/// @see https://github.com/chriseppstein/compass/pull/1352
/// @see https://github.com/Compass/compass/issues/1487
///
@mixin rhythm-context($new-base-font-size, $new-base-line-height) {
// Save the baseline context
$initial-font-size: $rhythm-base-font-size;
$initial-line-height: $rhythm-base-line-height;
// Apply the new context
$rhythm-base-font-size: $new-base-font-size !global;
$rhythm-base-line-height: $new-base-line-height !global;
// Render content passed to mixin
@content;
// Reapply the initial context
$rhythm-base-font-size: $initial-font-size !global;
$rhythm-base-line-height: $initial-line-height !global;
}
@include rhythm-establish;
.Box {
@include rhythm(16px);
}
@media (min-width:600px) {
.Box {
@include rhythm-context(16px, 28px) {
@include rhythm(12px, 4);
}
}
}
@charset "UTF-8";
/*! rhythm v0.1.4 – 14.10.2014 */
html {
font-size: 100%;
line-height: 1.3125em;
}
.Box {
font-size: 1rem;
line-height: 1.3125rem;
}
@media (min-width: 600px) {
.Box {
font-size: 0.75rem;
line-height: 7rem;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment