|
- /// Grid Math Engine
- /// ================
- /// The `su` functions give you direct access to the math layer,
- /// without any syntax-sugar like shorthand parsing, and normalization.
- /// If you prefer named arguments, and stripped-down syntax,
- /// you can use these functions directly in your code –
- /// replacing `span`, `gutter`, and `slice`.
- ///
- /// These functions are also useful
- /// for building mixins or other extensions to Susy.
- /// Apply the Susy syntax to new mixins and functions,
- /// using our "Plugin Helpers",
- /// or write your own syntax and pass the normalized results along
- /// to `su` for compilation.
- ///
- /// @group su-math
- ///
- /// @see su-span
- /// @see su-gutter
- /// @see su-slice
- /// @ignore _su-sum
- /// @ignore _su-calc-span
- /// @ignore _su-calc-sum
- /// @ignore _su-needs-calc-output
-
-
-
- // Su Span
- // -------
- /// Calculates and returns a CSS-ready span width,
- /// based on normalized span and context data –
- /// a low-level version of `susy-span`,
- /// with all of the logic and none of the syntax sugar.
- ///
- /// - Grids defined with unitless numbers will return `%` values.
- /// - Grids defined with comparable units
- /// will return a value in the units provided.
- /// - Grids defined with a mix of units,
- /// or a combination of untiless numbers and unit-lengths,
- /// will return a `calc()` string.
- ///
- /// @group su-math
- /// @see susy-span
- ///
- /// @param {number | list} $span -
- /// Number or list of grid columns to span
- /// @param {list} $columns -
- /// List of columns available
- /// @param {number} $gutters -
- /// Width of a gutter in column-comparable units
- /// @param {0 | 1 | -1} $spread -
- /// Number of gutters spanned,
- /// relative to `span` count
- /// @param {0 | 1 | -1} $container-spread [$spread] -
- /// Number of gutters spanned,
- /// relative to `columns` count
- /// @param {integer} $location [1] -
- /// Optional position of sub-span among full set of columns
- ///
- /// @return {length} -
- /// Relative or static length of a span on the grid
- @function su-span(
- $span,
- $columns,
- $gutters,
- $spread,
- $container-spread: $spread,
- $location: 1
- ) {
- $span: su-valid-span($span);
- $columns: su-valid-columns($columns);
- $gutters: su-valid-gutters($gutters);
- $spread: su-valid-spread($spread);
-
- @if (type-of($span) == 'number') {
- @if (not unitless($span)) {
- @return $span;
- }
-
- $location: su-valid-location($span, $location, $columns);
- $span: su-slice($span, $columns, $location, $validate: false);
- }
-
- @if _su-needs-calc-output($span, $columns, $gutters, $spread, not 'validate') {
- @return _su-calc-span($span, $columns, $gutters, $spread, $container-spread, not 'validate');
- }
-
- $span-width: _su-sum($span, $gutters, $spread, $validate: false);
-
- @if unitless($span-width) {
- $container-spread: su-valid-spread($container-spread);
- $container: _su-sum($columns, $gutters, $container-spread, $validate: false);
- @return percentage($span-width / $container);
- }
-
- @return $span-width;
- }
-
-
-
- // Su Gutter
- // ---------
- /// Calculates and returns a CSS-ready gutter width,
- /// based on normalized grid data –
- /// a low-level version of `susy-gutter`,
- /// with all of the logic and none of the syntax sugar.
- ///
- /// - Grids defined with unitless numbers will return `%` values.
- /// - Grids defined with comparable units
- /// will return a value in the units provided.
- /// - Grids defined with a mix of units,
- /// or a combination of untiless numbers and unit-lengths,
- /// will return a `calc()` string.
- ///
- /// @group su-math
- /// @see susy-gutter
- ///
- /// @param {list} $columns -
- /// List of columns in the grid
- /// @param {number} $gutters -
- /// Width of a gutter in column-comparable units
- /// @param {0 | 1 | -1} $container-spread -
- /// Number of gutters spanned,
- /// relative to `columns` count
- ///
- /// @return {length} -
- /// Relative or static length of one gutter in a grid
- @function su-gutter(
- $columns,
- $gutters,
- $container-spread
- ) {
- @if (type-of($gutters) == 'number') {
- @if ($gutters == 0) or (not unitless($gutters)) {
- @return $gutters;
- }
- }
-
- @if _su-needs-calc-output($gutters, $columns, $gutters, -1, not 'validate') {
- @return _su-calc-span($gutters, $columns, $gutters, -1, $container-spread, not 'validate');
- }
-
- $container: _su-sum($columns, $gutters, $container-spread);
- @return percentage($gutters / $container);
- }
-
-
-
- // Su Slice
- // --------
- /// Returns a list of columns
- /// based on a given span/location slice of the grid –
- /// a low-level version of `susy-slice`,
- /// with all of the logic and none of the syntax sugar.
- ///
- /// @group su-math
- /// @see susy-slice
- ///
- /// @param {number} $span -
- /// Number of grid columns to span
- /// @param {list} $columns -
- /// List of columns in the grid
- /// @param {number} $location [1] -
- /// Starting index of a span in the list of columns
- /// @param {bool} $validate [true] -
- /// Check that arguments are valid before proceeding
- ///
- /// @return {list} -
- /// Subset list of grid columns, based on span and location
- @function su-slice(
- $span,
- $columns,
- $location: 1,
- $validate: true
- ) {
- @if $validate {
- $columns: su-valid-columns($columns);
- $location: su-valid-location($span, $location, $columns);
- }
-
- $floor: floor($span);
- $sub-columns: ();
-
- @for $i from $location to ($location + $floor) {
- $sub-columns: append($sub-columns, nth($columns, $i));
- }
-
- @if $floor != $span {
- $remainder: $span - $floor;
- $column: $location + $floor;
- $sub-columns: append($sub-columns, nth($columns, $column) * $remainder);
- }
-
- @return $sub-columns;
- }
-
-
-
- // Su Sum
- // ------
- /// Get the total sum of column-units in a layout.
- ///
- /// @group su-math
- /// @access private
- ///
- /// @param {list} $columns -
- /// List of columns in the grid
- /// @param {number} $gutters -
- /// Width of a gutter in column-comparable units
- /// @param {0 | 1 | -1} $spread -
- /// Number of gutters spanned,
- /// relative to `columns` count
- /// @param {bool} $validate [true] -
- /// Check that arguments are valid before proceeding
- ///
- /// @return {number} -
- /// Total sum of column-units in a grid
- @function _su-sum(
- $columns,
- $gutters,
- $spread,
- $validate: true
- ) {
- @if $validate {
- $columns: su-valid-span($columns);
- $gutters: su-valid-gutters($gutters);
- $spread: su-valid-spread($spread);
- }
-
- // Calculate column-sum
- $column-sum: 0;
- @each $column in $columns {
- $column-sum: $column-sum + $column;
- }
-
- $gutter-sum: (ceil(length($columns)) + $spread) * $gutters;
- $total: if(($gutter-sum > 0), $column-sum + $gutter-sum, $column-sum);
-
- @return $total;
- }
-
-
-
- // Su Calc
- // -------
- /// Return a usable span width as a `calc()` function,
- /// in order to create mixed-unit grids.
- ///
- /// @group su-math
- /// @access private
- ///
- /// @param {number | list} $span -
- /// Pre-sliced list of grid columns to span
- /// @param {list} $columns -
- /// List of columns available
- /// @param {number} $gutters -
- /// Width of a gutter in column-comparable units
- /// @param {0 | 1 | -1} $spread -
- /// Number of gutters spanned,
- /// relative to `span` count
- /// @param {0 | 1 | -1} $container-spread [$spread] -
- /// Number of gutters spanned,
- /// relative to `columns` count
- /// @param {bool} $validate [true] -
- /// Check that arguments are valid before proceeding
- ///
- /// @return {length} -
- /// Relative or static length of a span on the grid
- @function _su-calc-span(
- $span,
- $columns,
- $gutters,
- $spread,
- $container-spread: $spread,
- $validate: true
- ) {
- @if $validate {
- $span: su-valid-span($span);
- $columns: su-valid-columns($columns);
- $gutters: su-valid-gutters($gutters);
- $spread: su-valid-spread($spread);
- $container-spread: su-valid-spread($container-spread);
- }
-
- // Span and context
- $span: _su-calc-sum($span, $gutters, $spread, not 'validate');
- $context: _su-calc-sum($columns, $gutters, $container-spread, not 'validate');
-
- // Fixed and fluid
- $fixed-span: map-get($span, 'fixed');
- $fluid-span: map-get($span, 'fluid');
- $fixed-context: map-get($context, 'fixed');
- $fluid-context: map-get($context, 'fluid');
-
- $calc: '#{$fixed-span}';
- $fluid-calc: '(100% - #{$fixed-context})';
-
- // Fluid-values
- @if (not $fluid-span) {
- $fluid-calc: null;
- } @else if ($fluid-span != $fluid-context) {
- $fluid-span: '* #{$fluid-span}';
- $fluid-context: if($fluid-context, '/ #{$fluid-context}', '');
- $fluid-calc: '(#{$fluid-calc $fluid-context $fluid-span})';
- }
-
- @if $fluid-calc {
- $calc: if(($calc != ''), '#{$calc} + ', '');
- $calc: '#{$calc + $fluid-calc}';
- }
-
- @return calc(#{unquote($calc)});
- }
-
-
-
- // Su Calc-Sum
- // -----------
- /// Get the total sum of fixed and fluid column-units
- /// for creating a mixed-unit layout with `calc()` values.
- ///
- /// @group su-math
- /// @access private
- ///
- /// @param {list} $columns -
- /// List of columns available
- /// @param {number} $gutters -
- /// Width of a gutter in column-comparable units
- /// @param {0 | 1 | -1} $spread -
- /// Number of gutters spanned,
- /// relative to `span` count
- /// @param {bool} $validate [true] -
- /// Check that arguments are valid before proceeding
- ///
- /// @return {map} -
- /// Map with `fixed` and `fluid` keys
- /// containing the proper math as strings
- @function _su-calc-sum(
- $columns,
- $gutters,
- $spread,
- $validate: true
- ) {
- @if $validate {
- $columns: su-valid-span($columns);
- $gutters: su-valid-gutters($gutters);
- $spread: su-valid-spread($spread);
- }
-
- $fluid: 0;
- $fixed: ();
- $calc: null;
-
- // Gutters
- $gutters: $gutters * (length($columns) + $spread);
-
- // Columns
- @each $col in append($columns, $gutters) {
- @if unitless($col) {
- $fluid: $fluid + $col;
- } @else {
- $fixed: _su-map-add-units($fixed, $col);
- }
- }
-
- // Compile Fixed Units
- @each $unit, $total in $fixed {
- @if ($total != (0 * $total)) {
- $calc: if($calc, '#{$calc} + #{$total}', '#{$total}');
- }
- }
-
- // Calc null or string
- @if $calc {
- $calc: if(str-index($calc, '+'), '(#{$calc})', '#{$calc}');
- }
-
- // Fluid 0 => null
- $fluid: if(($fluid == 0), null, $fluid);
-
-
- // Return map
- $return: (
- 'fixed': $calc,
- 'fluid': $fluid,
- );
-
- @return $return;
- }
-
-
-
- // Needs Calc
- // ----------
- /// Check if `calc()` will be needed in defining a span,
- /// if the necessary units in a grid are not comparable.
- ///
- /// @group su-math
- /// @access private
- ///
- /// @param {list} $span -
- /// Slice of columns to span
- /// @param {list} $columns -
- /// List of available columns in the grid
- /// @param {number} $gutters -
- /// Width of a gutter
- /// @param {0 | 1 | -1} $spread -
- /// Number of gutters spanned,
- /// relative to `span` count
- /// @param {bool} $validate [true] -
- /// Check that arguments are valid before proceeding
- ///
- /// @return {bool} -
- /// `True` when units do not match, and `calc()` will be required
- @function _su-needs-calc-output(
- $span,
- $columns,
- $gutters,
- $spread,
- $validate: true
- ) {
- @if $validate {
- $span: su-valid-span($span);
- $columns: su-valid-columns($columns);
- $gutters: su-valid-gutters($gutters);
- }
-
- $has-gutter: if((length($span) > 1) or ($spread >= 0), true, false);
- $check: if($has-gutter, append($span, $gutters), $span);
- $safe-span: _su-is-comparable($check...);
-
- @if ($safe-span == 'static') {
- @return false;
- } @else if (not $safe-span) {
- @return true;
- }
-
- $safe-fluid: _su-is-comparable($gutters, $columns...);
-
- @return not $safe-fluid;
- }
|