diff --git a/docs/pages/xy-grid.md b/docs/pages/xy-grid.md index ddfcc2db05..e3cc398500 100644 --- a/docs/pages/xy-grid.md +++ b/docs/pages/xy-grid.md @@ -402,7 +402,7 @@ This is especially powerful as you can specify where you want the gutters, like ### Cells Use the `xy-cell()` mixin to create a cell. There are a number of ways to define the size of a cell. -`xy-cell` accepts a few different keywords as well as specific sizes: `full` (full width), `auto` (automatic width) and `shrink` (take up only the space it needs). +`xy-cell` accepts a few different keywords as well as specific sizes: `full` (full width), `auto` (automatic width) and `shrink` (take up only the space it needs) or any fraction (`6`, `50%`, `1 of 2` or `1/2`...). ```scss .main-content { @@ -428,6 +428,24 @@ The cell size calculator can also be accessed as a function. This gives you the } ``` +A cell is composed of 3 parts: the base, the size and the gutters. In order to avoid duplicating properties, you can choose the parts to generate with the `$output` option, or call the XY cell mixins dedicated to each part individually. + +```scss +.my-cell { + @include xy-cell(12, $gutters: none); +} +.my-cell.half-size { + @include xy-cell(6, $gutters: none, $output: (size)); + // Or @include xy-cell-size(6); +} +``` + +
+ XY cell with margin gutters (by default) has gutters defined within their width/height. For this reason, you need to generate the gutter part of cells with margin gutters even when you only want to change the size. +
+ +Refer to the Sass documentation of the [xy-cell](#xy-cell) mixin for the full list of arguments. See also [xy-cell-base](#xy-cell-base), [xy-cell-size](#xy-cell-size) and [xy-cellgutters](#xy-cellgutters). + --- ### Responsive Grids diff --git a/scss/grid/_column.scss b/scss/grid/_column.scss index cddf6e4943..26c8d15cdd 100644 --- a/scss/grid/_column.scss +++ b/scss/grid/_column.scss @@ -16,37 +16,7 @@ /// /// @returns {Number} A calculated percentage value. @function grid-column($columns) { - $width: 0%; - - // Parsing percents, decimals, and column counts - @if type-of($columns) == 'number' { - @if unit($columns) == '%' { - $width: $columns; - } - @else if $columns < 1 { - $width: percentage($columns); - } - @else { - $width: percentage($columns / $grid-column-count); - } - } - - // Parsing "n of n" expressions - @else if type-of($columns) == 'list' { - @if length($columns) != 3 { - @error 'Wrong syntax for grid-column(). Use the format "n of n".'; - } - @else { - $width: percentage(nth($columns, 1) / nth($columns, 3)); - } - } - - // Anything else is incorrect - @else { - @error 'Wrong syntax for grid-column(). Use a number, decimal, percentage, or "n of n".'; - } - - @return $width; + @return fraction-to-percentage($columns, $denominator: $grid-column-count); } /// Creates a grid column. diff --git a/scss/util/_breakpoint.scss b/scss/util/_breakpoint.scss index 897db23324..8f7fab6326 100644 --- a/scss/util/_breakpoint.scss +++ b/scss/util/_breakpoint.scss @@ -328,6 +328,28 @@ $breakpoint-classes: (small medium large) !default; } } +/// Return the best breakpoint to use according to the calling context. It returns in order: +/// 1. the given `$value` argument if it is not null. +/// 2. the global breakpoint context `$-zf-size` if it is not null (like if called inside then `breakpoint()` mixin) +/// 3. the given `$default` argument. +/// @access private +/// +/// @param {Keyword} $value [null] - Breakpoint to use in priority if non-null. +/// @param {Keyword} $default [null] - Breakpoint to use by default if no other value can be used. +/// +/// @return {Keyword} The resolved breakpoint. +@function -zf-current-breakpoint($value: null, $default: null) { + @if ($value != null) { + @return $value; + } + @else if (variable-exists(-zf-size) and type-of($-zf-size) != 'number') and $-zf-size != null { + @return $-zf-size; + } + @else { + @return $default; + } +} + $small-up: ''; $small-only: ''; diff --git a/scss/util/_math.scss b/scss/util/_math.scss index e3d1908864..947a576e5d 100644 --- a/scss/util/_math.scss +++ b/scss/util/_math.scss @@ -70,3 +70,78 @@ $h: nth($ratio, 3); @return $h / $w * 100%; } + +/// Parse the given `$fraction` to numerators and denumerators. +/// +/// @param {*} $fraction - Value representing a fraction to parse. It can be formatted as `50%`, `1 of 2`, `1/2` or `50` (no denominator would be returned). +/// +/// @return {List} List of parsed values with numerator at first position and denumerator as second. These values may be null. +@function zf-parse-fraction($fraction) { + + @if type-of($fraction) == 'number' { + // "50%" + @if unit($fraction) == '%' { + @return (strip-unit($fraction), 100); + } + @else if (unit($fraction) == '') { + // "0.5" + @if $fraction < 1 { + @return ($fraction * 100, 100); + } + // "50" + @else { + @return ($fraction, null); + } + } + } + + @else if type-of($fraction) == 'list' { + // "50 of 100", "50/100"... + @if length($fraction) == 3 + and type-of(nth($fraction, 1) == 'number') + and type-of(nth($fraction, 3) == 'number') { + @return (nth($fraction, 1), nth($fraction, 3)); + } + } + + @return (null, null); +} + +/// Returns whether the given `$value` represents a fraction. Supports formats like `50%`, `1 of 2`, `1 per 2` or `1/2`. +/// +/// @param {*} $value - Value to test. +/// @param {Boolean} $allow-no-denominator [false] - If `true`, simple numbers without denominators like `50` are supported. +/// +/// @return {Boolean} `true` if `$value` represents a fraction, `false` otherwise. +@function zf-is-fraction($value, $allow-no-denominator: false) { + $parsed: zf-parse-fraction($value); + @return not(nth($parsed, 1) == null + or (nth($parsed, 2) == null and $allow-no-denominator == false)); +} + +/// Calculate a percentage from a given fraction. +/// +/// @param {Number|List} $fraction - Value representing a fraction to use to calculate the percentage, formatted as `50` (relative to `$denominator`), `50%`, `1 of 2` or `1/2`. +/// @param {Number|List} $denominator - Default value to use as denominator when `$fraction` represents an absolute value. +@function fraction-to-percentage( + $fraction, + $denominator: null +) { + $parsed: zf-parse-fraction($fraction); + $parsed-nominator: nth($parsed, 1); + $parsed-denominator: nth($parsed, 2); + + @if $parsed-nominator == null { + @error 'Wrong syntax for "fraction-to-percentage()". Use a number, decimal, percentage, or "n of n" / "n/n".'; + } + @if $parsed-denominator == null { + @if type-of($denominator) == 'number' { + $parsed-denominator: $denominator; + } + @else { + @error 'Error with "fraction-to-percentage()". A default "$denominator" is required to support absolute values'; + } + } + + @return percentage($parsed-nominator / $parsed-denominator); +} diff --git a/scss/util/_mixins.scss b/scss/util/_mixins.scss index 89ef0c3ff1..c256dc6001 100644 --- a/scss/util/_mixins.scss +++ b/scss/util/_mixins.scss @@ -268,22 +268,64 @@ /// /// @param {Boolean} $small [true] - If `false`, the mixin will skip the `small` breakpoint. Use this with components that don't prefix classes with `small-`, only `medium-` and up. /// @param {Boolean} $auto-insert-breakpoints [true] - If `false`, the mixin will iterate over breakpoints without doing the media query itself. Useful for more complex media query generation as in the margin grid. -@mixin -zf-each-breakpoint($small: true, $auto-insert-breakpoints: true) { - $list: $breakpoint-classes; +@mixin -zf-each-breakpoint( + $small: true, + $auto-insert-breakpoints: true +) { + @include -zf-each-breakpoint-in(auto, -zf-bool($small), -zf-bool($auto-insert-breakpoints)) { + @content + }; +} + +/// Iterates with `@content` through the given list of breakpoints `$breakpoints`. +/// +/// @access private +/// +/// @param {Keyword|List} $breakpoints [auto] - Breakpoints to iterates on. It can be a breakpoint name, list of breakpoints or `auto` for all breakpoints. +/// @param {Boolean|Null} $zero-breakpoint [null] - Whether the zero-breakpoint (often `small`) must be included. If `true`, it will always be added to the list if not already there. If `false`, it will always be removed. Does nothing by default. +/// @param {Boolean|Keyword} $media-queries [true] - Whether media-queries must be generated. If `for-lists`, only generate media-queries when `$breakpoints` is a list. +@mixin -zf-each-breakpoint-in( + $breakpoints: auto, + $zero-breakpoint: null, + $media-queries: true +) { + $-list: (); + $-breakpoints-is-a-list: true; + + // Retrieve the list of breakpoint(s) to iterate on. + @if $breakpoints == auto { + $-list: $breakpoint-classes; + } + @else if type-of($breakpoints) == 'list' { + $-list: $breakpoints; + } + @else if type-of($breakpoints) == 'string' { + $-list: ($breakpoints); + $-breakpoints-is-a-list: false; + } + @else { + @error 'Wrong syntax for "$breakpoints" in "-zf-each-breakpoint-in()". Got "#{$breakpoints}" (#{type-of($breakpoints)}). Expected a breakpoint name, a list of breakpoints or "auto"'; + } - @if not $small { - $list: sl-remove($list, $-zf-zero-breakpoint); + // Add or remove the zero breakpoint according to `$zero-breakpoint` + @if $zero-breakpoint == true { + $-list: join(($-zf-zero-breakpoint), sl-remove($-list, $-zf-zero-breakpoint)); + } + @else if $zero-breakpoint == false { + $-list: sl-remove($-list, $-zf-zero-breakpoint); } - @each $name in $list { + // Iterate on breakpoint(s) + @each $bp in $-list { $old-zf-size: null; @if global-variable-exists(-zf-size) { $old-zf-size: $-zf-size; } - $-zf-size: $name !global; + $-zf-size: $bp !global; - @if $auto-insert-breakpoints { - @include breakpoint($name) { + @if ($media-queries == true + or ($media-queries == 'for-lists' and $-breakpoints-is-a-list)) { + @include breakpoint($bp) { @content; } } @@ -318,7 +360,10 @@ @else { // breakpoint name @if type-of($name) == 'string' { - $name: -zf-get-bp-val($map, $name); + $bp-value: -zf-get-bp-val($map, $name); + @if $bp-value != null { + $name: $bp-value; + } } // breakpoint value diff --git a/scss/util/_value.scss b/scss/util/_value.scss index a063a82af6..cde5d37f89 100644 --- a/scss/util/_value.scss +++ b/scss/util/_value.scss @@ -158,3 +158,14 @@ @error '`#{$map}` is not a valid map'; } } + +/// Convert the given `$val` to a Boolean. Empty values are considered as false. +//// +/// @access private +/// +/// @param {*} $val - Value to convert. +/// +/// @returns {Boolean} Converted Boolean value. +@function -zf-bool($val) { + @return $val != false and has-value($val); +} diff --git a/scss/xy-grid/_cell.scss b/scss/xy-grid/_cell.scss index 5ed44c80c1..b851b6ab61 100644 --- a/scss/xy-grid/_cell.scss +++ b/scss/xy-grid/_cell.scss @@ -6,150 +6,244 @@ /// @group xy-grid //// -/// Calculate the percentage size of a cell. +/// Returns the appropriate CSS flex value for a cell base. +/// +/// @param {Keyword} $size [full] - The size of your cell. Accepts `full`, `auto`, `shrink`, `grow`, or any other value representing a cell size (it will be treated as `shrink`). +/// +/// @returns {List} The cell flex property value. +@function xy-cell-base($size: full) { + @if ($size == 'auto') { + @return 1 1 0px; + } + @else if ($size == 'grow') { + @return 1 0 auto; + } + @else if ($size == 'shrink' or $size == 'full' or zf-is-fraction($size, $allow-no-denominator: true)) { + @return 0 0 auto; + } + @return null; +} + +/// Calculate the size of a cell gutters. +/// +/// @param {Number|Map} $gutters [$grid-margin-gutters] - Map or single value for gutters. +/// @param {String} $breakpoint [null] - The name of the breakpoint size in your gutters map to get the size from. If `auto`, returns the responsive gutters map `$gutters`. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. +/// +/// @returns {Number|Map} The cell gutter size or the responsive gutters map. +@function xy-cell-gutters( + $gutters: $grid-margin-gutters, + $breakpoint: null +) { + // For `auto`, returns the responsive map `$gutters`. + @if ($breakpoint == 'auto') { + @return $gutters; + } + + // Use the contextual breakpoint by default. + $breakpoint: -zf-current-breakpoint($breakpoint); + + @if ($breakpoint) { + @return -zf-get-bp-val($gutters, $breakpoint); + } + @else { + @return -zf-get-bp-val($gutters, $-zf-zero-breakpoint) or 0; + } +} + +/// Returns the percentage size of a cell. /// /// @param {Number|List} $size [$grid-columns] - Size to make the cell. You can pass a value in multiple formats, such as `6`, `50%`, `1 of 2` or `1/3`. +/// +/// @returns {Number} Size of the cell (in percent). @function xy-cell-size( $size: $grid-columns ) { - // Parsing percents, decimals, n of n and number counts - @if type-of($size) == 'number' { - @if unit($size) == '%' { - $size: $size; - } - @else if $size < 1 { - $size: percentage($size); - } - @else { - $size: percentage($size / $grid-columns); - } + @return fraction-to-percentage($size, $denominator: $grid-columns); +} + +/// Returns the appropriate CSS value for a cell size. +/// +/// Gutters-related arguments are required for cells with margin gutters (by default) as the gutter is included in the width. +/// +/// @param {Keyword|Number} $size [full] - The size of your cell. Can be `full`, `auto`, `shrink` or any fraction like `6`, `50%`, `1 of 2` or `1/2`. +/// @param {Number|Map} $gutters [$grid-margin-gutters] - Map or single value for gutters. +/// @param {Keyword} $gutter-type [margin] - Type of gutter to output. Accepts `margin`, `padding` or `none`. +/// @param {String} $breakpoint [null] - The name of the breakpoint size in your gutters map to get the size from. If `auto`, returns a map of sizes adapted to responsive gutters. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. +/// +/// @returns {Number|String|Map} The cell sizing property value, or a responsive map of them. +@function xy-cell-size-css( + $size: full, + $gutters: $grid-margin-gutters, + $gutter-type: margin, + $breakpoint: null +) { + $margin-gutter: 0; + + @if ($size == 'auto' or $size == 'shrink') { + @return auto; } - // Parsing "n of n" or "n/n" expressions - @else if type-of($size) == 'list' { - @if length($size) != 3 { - @error 'Wrong syntax for xy-cell-size(). Use the format "n of n" or "n/n".'; + // For cells with margin gutters, the gutter is included in the width. + @if ($gutter-type == 'margin') { + $margin-gutter: xy-cell-gutters($gutters, $breakpoint); + @if ($margin-gutter == null) { + @error 'xy-cell-size: no gutters were found in `$gutters` for "$breakpoint: #{$breakpoint}"'; } - @else { - $size: percentage(nth($size, 1) / nth($size, 3)); + } + + // Calculate the cell size (number) + $size-raw: if($size == 'full', 100%, xy-cell-size($size)); + + // Calculate the cell CSS size including gutters (string) + // If the cell has responsive margin gutters, return a responsive map of sizes. + @if type-of($margin-gutter) == 'map' { + $responsive-css-sizes: (); + + @each $bp, $mg in $margin-gutter { + $size-css: if($mg == 0, $size-raw, calc(#{$size-raw} - #{rem-calc($mg)})); + $responsive-css-sizes: map-merge($responsive-css-sizes, ($bp: $size-css)); } + + @return $responsive-css-sizes; } - // Anything else is incorrect + // Otherwise, return a single CSS size. @else { - @error 'Wrong syntax for xy-cell-size(). Use a number, decimal, percentage, or "n of n" / "n/n".'; + $css-size: if($margin-gutter == 0, $size-raw, calc(#{$size-raw} - #{rem-calc($margin-gutter)})); + @return $css-size; } - - @return $size; } /// Sets base flex properties for cells. /// -/// @param {Keyword} $size [full] - The size of your cell. Accepts `full`, `auto`, `shrink` or `grow`. +/// @param {Keyword} $size [full] - The size of your cell. Accepts `full`, `auto`, `shrink`, `grow`, or any other value representing a cell size (it will be treated as `shrink`). @mixin xy-cell-base($size: full) { + $base: xy-cell-base($size); + + flex: #{$base}; + + // Set base styles for "full" only @if($size == 'full') { - // This is the base style, all others inherit from it - flex: 0 0 auto; min-height: 0px; min-width: 0px; } - @else if ($size == 'auto') { - flex: 1 1 0px; // sass-lint:disable-line zero-unit - } - @else if ($size == 'shrink') { - flex: 0 0 auto; - } - @else if ($size == 'grow') { - flex: 1 0 auto; - } } /// Resets a cells width (or height if vertical is true) as well as strips its gutters. /// /// @param {Boolean} $vertical [false] - Set to true to output vertical (height) styles rather than widths. @mixin xy-cell-reset($vertical: true) { - $direction: if($vertical == true, width, height); + $direction: if($vertical == true, height, width); #{$direction}: auto; max-#{$direction}: none; } -// Sets our cell widths or heights depending on gutter type. -@mixin -xy-cell-properties($size, $margin-gutter, $vertical) { +/// Sets sizing properties for cells. +/// +/// Gutters-related arguments are required for cells with margin gutters (by default) as the gutter is included in the width. +/// +/// @param {Keyword|Number} $size [full] - The size of your cell. Can be `full` (100% width), `auto` (use all available space), `shrink` (use only the required space) or any fraction (`6`, `50%`, `1 of 2` or `1/2`...). +/// @param {Number|Map} $gutters [$grid-margin-gutters] - Map or single value for gutters. +/// @param {Keyword} $gutter-type [margin] - Type of gutter to output. Accepts `margin`, `padding` or `none`. +/// @param {String} $breakpoint [null] - The name of the breakpoint size in your gutters map to get the size from. If `auto`, generates sizes adapted for responsive gutters. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. +/// @param {Boolean} $vertical [false] - Set to true to output vertical (height) styles rather than widths. +@mixin xy-cell-size( + $size: full, + $gutters: $grid-margin-gutters, + $gutter-type: margin, + $breakpoint: null, + $vertical: false +) { + $sizes: xy-cell-size-css($size, $gutters, $gutter-type, $breakpoint); $direction: if($vertical == true, height, width); - @if($size == 'full') { - $val: if($margin-gutter == 0, 100%, calc(100% - #{rem-calc($margin-gutter)})); - #{$direction}: $val; + + @if (type-of($sizes) == 'map') { + @include -zf-breakpoint-value(auto, $sizes) { + #{$direction}: $-zf-bp-value; + } } - @else if ($size == 'auto') { - #{$direction}: auto; - $val: if($margin-gutter == 0, 100%, calc(100% - #{rem-calc($margin-gutter)})); + @else { + #{$direction}: $sizes; + } +} + +/// Sets gutters properties for cells. +/// +/// @param {Number|Map} $gutters [$grid-margin-gutters] - Map or single value for gutters. +/// @param {Keyword} $gutter-type [margin] - Type of gutter to output. Accepts `margin`, `padding` or `none`. +/// @param {List} $gutter-position [null] - The position to apply gutters to. Accepts `top`, `bottom`, `left`, `right` in any combination. By default `right left` for horizontal cells and `top bottom` for vertical cells. +/// @param {String} $breakpoint [null] - The name of the breakpoint size in your gutters map to get the size from. If `auto`, generates responsive gutters. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. +/// @param {Boolean} $vertical [false] - Direction of the gutters to output. See `$gutter-position`. +@mixin xy-cell-gutters( + $gutters: $grid-margin-gutters, + $gutter-type: margin, + $gutter-position: null, + $breakpoint: null, + $vertical: false +) { + // Get the default gutter position according to cell direction + @if($gutter-position == null) { + $gutter-position: if($vertical == true, top bottom, left right); } - @else if ($size == 'shrink') { - #{$direction}: auto; + + // Get the gutter width for this breakpoint + $gutter-width: xy-cell-gutters($gutters, $breakpoint); + @if ($gutter-width == null) { + @error 'xy-cell-gutters: no gutters were found in `$gutters` for "$breakpoint: #{$breakpoint}"'; } - @else { - $val: if($margin-gutter == 0, #{xy-cell-size($size)}, calc(#{xy-cell-size($size)} - #{rem-calc($margin-gutter)})); - #{$direction}: $val; + + @if ($gutter-type and $gutter-type != none) { + @include xy-gutters($gutter-width, $gutter-type, $gutter-position); } } /// Creates a cell for your grid. /// -/// @param {Keyword|Number} $size [full] - The size of your cell. Can be `full` (default) for 100% width, `auto` to use up available space and `shrink` to use up only required space. -/// @param {Boolean} $gutter-output [true] - Whether or not to output gutters. Always `true` for margin gutters. +/// @param {Keyword|Number} $size [full] - The size of your cell. Can be `full` (100% width), `auto` (use all available space), `shrink` (use only the required space) or any fraction (`6`, `50%`, `1 of 2` or `1/2`...). +/// @param {Boolean} $gutter-output [null] - [DEPRECATED] Whether or not to output gutters. /// @param {Number|Map} $gutters [$grid-margin-gutters] - Map or single value for gutters. -/// @param {Keyword} $gutter-type [margin] - Map or single value for gutters. -/// @param {List} $gutter-position [right left] - The position to apply gutters to. Accepts `top`, `bottom`, `left`, `right` in any combination. -/// @param {String} $breakpoint [null] - The name of the breakpoint size in your gutters map to get the size from. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. +/// @param {Keyword} $gutter-type [margin] - Type of gutter to output. Accepts `margin`, `padding` or `none`. +/// @param {List} $gutter-position [null] - The position to apply gutters to. Accepts `top`, `bottom`, `left`, `right` in any combination. By default `right left` for horizontal cells and `top bottom` for vertical cells. +/// @param {String} $breakpoint [null] - The name of the breakpoint size in your gutters map to get the size from. If `auto`, generates responsive gutters. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. /// @param {Boolean} $vertical [false] - Set to true to output vertical (height) styles rather than widths. +/// @param {List} $output [(base size gutters)] - Cell parts to output. You will need to generate others parts of the cell seperately, it may not work properly otherwise. @mixin xy-cell( $size: full, - $gutter-output: true, + $gutter-output: null, $gutters: $grid-margin-gutters, $gutter-type: margin, - $gutter-position: right left, + $gutter-position: null, $breakpoint: null, - $vertical: false + $vertical: false, + $output: (base size gutters) ) { - $bp-is-fallback: false; - - @if($breakpoint == null) { - // If `$bp-size` is available then use this, otherwise revert to the smallest bp. - @if(variable-exists(-zf-size) and type-of($-zf-size) != 'number') and $-zf-size != null { - $breakpoint: $-zf-size; + // Default for $gutter-output + @if ($gutter-output != null) { + @warn 'xy-cell: $gutter-output is deprecated and will be removed. See migration notes at https://git.io/foundation-6-6-0'; + @if ($gutter-output == false) { + $output: sl-remove($output, gutters); } - @else { - $breakpoint: $-zf-zero-breakpoint; - $bp-is-fallback: true; - } - } - - // Get the gutter for the given breakpoint/value. - $gutter: -zf-get-bp-val($gutters, $breakpoint); - // If the breakpoint is a fallback, use a fallback gutter as well - @if ($bp-is-fallback == true and $gutter == null) { - $gutter: 0; } - @if($gutter != null) { - // Base flex properties + @if (index($output, base)) { @include xy-cell-base($size); - - $-gutter-output: if($gutter-type == 'margin', true, $gutter-output); - $-gutter-margin: if($gutter-type == 'margin', $gutter, 0); - - @include -xy-cell-properties($size, $-gutter-margin, $vertical); - @if ($-gutter-output) { - @include xy-gutters($gutter, $gutter-type, $gutter-position); - } } - @else { - @warn 'xy-cell: no gutters were found in `$gutters` for "$breakpoint: #{$breakpoint}", cell was not generated`' + @if (index($output, size)) { + @include xy-cell-size($size, $gutters, $gutter-type, $breakpoint, $vertical); + } + @if (index($output, gutters)) { + @include xy-cell-gutters($gutters, $gutter-type, $gutter-position, $breakpoint, $vertical); } } /// Creates a single breakpoint sized grid. Used to generate our grid classes. /// -/// @param {Keyword|Number} $size [full] - The size of your cell. Can be `full` (default) for 100% width, `auto` to use up available space and `shrink` to use up only required space. +/// `xy-cell-static()` is deprecated and will be removed. +/// Use `xy-cell()` instead with `$output: (size gutters)` to not generate the cell base. +/// See migration notes at https://git.io/foundation-6-6-0 +/// +/// @deprecated v6.6.0 +/// +/// @param {Keyword|Number} $size [full] - The size of your cell. Can be `full` (100% width), `auto` (use all available space), `shrink` (use only the required space) or any fraction (`6`, `50%`, `1 of 2` or `1/2`...). /// @param {Boolean} $gutter-output [true] - Whether or not to output gutters. Always `true` for margin gutters. /// @param {Number|Map} $gutters [$grid-margin-gutters] - Map or single value for gutters. /// @param {Keyword} $gutter-type [margin] - Map or single value for gutters. @@ -163,6 +257,7 @@ $breakpoint: $-zf-zero-breakpoint, $vertical: false ) { + @warn 'xy-cell-static() mixin is deprecated and will be removed. Use "xy-cell()" instead. See migration notes at https://git.io/foundation-6-6-0'; $gutter: -zf-get-bp-val($gutters, $breakpoint); $gutter-position: if($vertical == true, top bottom, left right); diff --git a/scss/xy-grid/_classes.scss b/scss/xy-grid/_classes.scss index eccf9986a7..eeb1410cb9 100644 --- a/scss/xy-grid/_classes.scss +++ b/scss/xy-grid/_classes.scss @@ -28,8 +28,7 @@ } .cell { - @include xy-cell-base(); - @include xy-cell-static($grid-columns, false, $gutter-type: padding); + @include xy-cell(full, $gutter-type: none); &.auto { @include xy-cell-base(auto); @@ -42,11 +41,11 @@ } .grid-x { > .auto { - @include xy-cell-static(auto, false); + @include xy-cell-size(auto, $gutter-type: none); } > .shrink { - @include xy-cell-static(shrink, false); + @include xy-cell-size(shrink, $gutter-type: none); } } @@ -71,8 +70,7 @@ // Responsive "auto" modifier @if not($-zf-size == small) { .grid-x > .#{$-zf-size}-auto { - @include xy-cell-base(auto); - @include xy-cell-static(auto, false); + @include xy-cell(auto, $gutter-type: none); } } @@ -84,7 +82,7 @@ @if not($-zf-size == small) { .grid-x > .#{$-zf-size}-shrink { @extend %-xy-cell-base-shrink-horizontal-#{$-zf-size}; - @include xy-cell-static(shrink, false); + @include xy-cell-size(shrink, $gutter-type: none); } } @@ -93,7 +91,7 @@ // Sizing (percentage) .grid-x > .#{$-zf-size}-#{$i} { @extend %-xy-cell-base-shrink-horizontal-#{$-zf-size}; - @include xy-cell-static($i, false, $gutter-type: padding); + @include xy-cell-size($i, $gutter-type: none); } } } @@ -112,11 +110,11 @@ @mixin -xy-breakpoint-cell-classes($class-breakpoint, $gutter-breakpoint, $vertical) { $prefix: if($class-breakpoint == $-zf-zero-breakpoint, '', '#{$class-breakpoint}-'); > .#{$prefix}auto { - @include xy-cell-static(auto, false, $breakpoint: $gutter-breakpoint, $vertical: $vertical); + @include xy-cell-size(auto, $vertical: $vertical); } > .#{$prefix}shrink { - @include xy-cell-static(shrink, false, $breakpoint: $gutter-breakpoint, $vertical: $vertical); + @include xy-cell-size(shrink, $vertical: $vertical); } @for $i from 1 through $grid-columns { @@ -124,7 +122,7 @@ $classname: if($vertical, '.#{$class-breakpoint}-#{$i}', '.#{$class-breakpoint}-#{$i}'); > #{$classname} { - @include xy-cell-static($i, false, $breakpoint: $gutter-breakpoint, $vertical: $vertical); + @include xy-cell-size($i, $vertical: $vertical); } } } @@ -140,14 +138,14 @@ // Base cell styles > .cell { - @include xy-cell-static($vertical: $vertical); + @include xy-cell($vertical: $vertical, $output: (size gutters)); } // base styles need to all be before the auto and shrink styles @include -zf-each-breakpoint() { @if(type-of($grid-margin-gutters) == 'map' and map-has-key($grid-margin-gutters, $-zf-size) and $-zf-size != $-zf-zero-breakpoint) { > .cell { - @include xy-cell-static($breakpoint: $-zf-size, $vertical: $vertical); + @include xy-cell($vertical: $vertical, $output: (size gutters)); } } } @@ -197,7 +195,7 @@ @include -zf-each-breakpoint { @for $i from 1 through $xy-block-grid-max { .#{$-zf-size}-up-#{$i} { - @include xy-grid-layout($n: $i, $selector: '.cell', $gutter-output: false, $gutter-type: padding, $breakpoint: $-zf-size); + @include xy-grid-layout($n: $i, $selector: '.cell', $gutter-type: padding, $output: (size)); } } } @@ -212,7 +210,7 @@ @each $bp in -zf-breakpoints-less-than($-zf-size) { @if(map-has-key($grid-margin-gutters, $bp)) { .grid-margin-x.#{$bp}-up-#{$i} { - @include xy-grid-layout($n: $i, $selector: '.cell', $gutter-output: false, $gutter-type: margin, $breakpoint: $-zf-size); + @include xy-grid-layout($n: $i, $selector: '.cell', $gutter-type: margin, $output: (size)); } } } @@ -220,7 +218,7 @@ } @for $i from 1 through $xy-block-grid-max { .grid-margin-x.#{$-zf-size}-up-#{$i} { - @include xy-grid-layout($n: $i, $selector: '.cell', $gutter-output: false, $gutter-type: margin, $breakpoint: $-zf-size); + @include xy-grid-layout($n: $i, $selector: '.cell', $gutter-type: margin, $output: (size)); } } } @@ -252,11 +250,11 @@ $o: $i - 1; .#{$-zf-size}-offset-#{$o} { - @include xy-cell-offset($o, $gutters: $grid-padding-gutters, $gutter-type: padding, $breakpoint: $-zf-size); + @include xy-cell-offset($o, $gutters: $grid-padding-gutters, $gutter-type: padding); } .grid-margin-x > .#{$-zf-size}-offset-#{$o} { - @include xy-cell-offset($o, $breakpoint: $-zf-size); + @include xy-cell-offset($o); } } } @@ -282,11 +280,11 @@ } > .auto { - @include xy-cell-static(auto, false, $vertical: true); + @include xy-cell-size(auto, $gutter-type: none, $vertical: true); } > .shrink { - @include xy-cell-static(shrink, false, $vertical: true); + @include xy-cell-size(shrink, $gutter-type: none, $vertical: true); } @@ -308,8 +306,7 @@ // Responsive "auto" modifier @if not($-zf-size == small) { > .#{$-zf-size}-auto { - @include xy-cell-base(auto); - @include xy-cell-static(auto, false, $breakpoint: $-zf-size, $vertical: true); + @include xy-cell(auto, $gutter-type: none, $vertical: true); } } @@ -321,7 +318,7 @@ @if not($-zf-size == small) { > .#{$-zf-size}-shrink { @extend %-xy-cell-base-shrink-vertical-#{$-zf-size}; - @include xy-cell-static(shrink, false, $breakpoint: $-zf-size, $vertical: true); + @include xy-cell-size(shrink, $gutter-type: none, $vertical: true); } } @@ -330,7 +327,7 @@ // Sizing (percentage) > .#{$-zf-size}-#{$i} { @extend %-xy-cell-base-shrink-vertical-#{$-zf-size}; - @include xy-cell-static($i, false, $vertical: true, $gutter-type: padding); + @include xy-cell-size($i, $gutter-type: none, $vertical: true); } } diff --git a/scss/xy-grid/_collapse.scss b/scss/xy-grid/_collapse.scss index 861608f9e1..76b692f633 100644 --- a/scss/xy-grid/_collapse.scss +++ b/scss/xy-grid/_collapse.scss @@ -42,7 +42,7 @@ @for $i from 1 through $grid-columns { // Sizing (percentage) > .#{$bp}-#{$i} { - @include xy-cell-static($i, $gutter-output: false, $gutter-type: padding); + @include xy-cell-size($i, $gutter-type: none); } } } @@ -51,7 +51,7 @@ @for $i from 1 through $grid-columns { // Sizing (percentage) > .#{$bp}-#{$i} { - @include xy-cell-static($i, $gutter-output: false, $gutter-type: padding); + @include xy-cell-size($i, $gutter-type: none); } } } diff --git a/scss/xy-grid/_layout.scss b/scss/xy-grid/_layout.scss index 0ac87584e2..f8c91f6972 100644 --- a/scss/xy-grid/_layout.scss +++ b/scss/xy-grid/_layout.scss @@ -10,25 +10,27 @@ /// /// @param {Number} $n - Number of elements to display per row. /// @param {String} $selector ['.cell'] - Selector(s) to use for child elements. -/// @param {Boolean} $gutter-output [true] - Whether or not to output gutters. Always `true` for margin gutters. +/// @param {Boolean} $gutter-output [null] - [DEPRECATED] Whether or not to output gutters. /// @param {Number|Map} $gutters [$grid-margin-gutters] - Map or single value for gutters. -/// @param {Keyword} $gutter-type [margin] - Type of gutter to output. Accepts `margin` or `padding`. -/// @param {List} $gutter-position [right left] - The position to apply gutters to. Accepts `top`, `bottom`, `left`, `right` in any combination. -/// @param {String} $breakpoint [null] - The breakpoint to use for the cell generation. +/// @param {Keyword} $gutter-type [margin] - Type of gutter to output. Accepts `margin`, `padding` or `none`. +/// @param {List} $gutter-position [null] - The position to apply gutters to. Accepts `top`, `bottom`, `left`, `right` in any combination. By default `right left` for horizontal cells and `top bottom` for vertical cells. +/// @param {String} $breakpoint [null] - The breakpoint to use for the cell generation. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. /// @param {Boolean} $vertical [false] - Set to true to output vertical (height) styles rather than widths. +/// @param {List} $output [(base size gutters)] - Cell parts to output. You will need to generate others parts of the cell seperately, it may not work correctly otherwise. @mixin xy-grid-layout( $n, $selector: '.cell', - $gutter-output: true, + $gutter-output: null, $gutters: $grid-margin-gutters, $gutter-type: margin, - $gutter-position: right left, + $gutter-position: null, $breakpoint: null, - $vertical: false + $vertical: false, + $output: (base size gutters) ) { $size: percentage(1/$n); & > #{$selector} { - @include xy-cell($size, $gutter-output, $gutters, $gutter-type, $gutter-position, $breakpoint, $vertical); + @include xy-cell($size, $gutter-output, $gutters, $gutter-type, $gutter-position, $breakpoint, $vertical, $output); } } diff --git a/scss/xy-grid/_position.scss b/scss/xy-grid/_position.scss index 336275de5b..f20a07c05d 100644 --- a/scss/xy-grid/_position.scss +++ b/scss/xy-grid/_position.scss @@ -6,27 +6,50 @@ /// @group xy-grid //// +/// Returns the appropriate CSS value to offset a cell. +/// +/// @param {Number|List} $n - Size to offset by. You can pass in any value accepted by the `xy-cell()` mixin, such as `6`, `50%`, or `1 of 2`. +/// @param {Number|Map} $gutters [$grid-margin-gutters] Map of gutters or single value to use for responsive gutters. +/// @param {Keyword} $gutter-type [margin] The type of gutter to use. Can be `margin` or `padding` +/// @param {String} $breakpoint [null] - The name of the breakpoint size in your gutters map to get the size from. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. +/// +/// @returns {Number|String} The cell offset property value. +@function xy-cell-offset( + $n, + $gutters: $grid-margin-gutters, + $gutter-type: margin, + $breakpoint: null +) { + $breakpoint: -zf-current-breakpoint($breakpoint, $default: $-zf-zero-breakpoint); + $size: xy-cell-size($n); + + $offset: $size; + @if ($gutter-type == 'margin') { + $gutter: rem-calc(xy-cell-gutters($gutters, $breakpoint) / 2); + $offset: if($gutter == 0, $size, calc(#{$size} + #{$gutter})); + } + @return $offset; +} + /// Offsets a column to the right/bottom by `$n` columns. /// -/// @param {Number|List} $n - Size to offset by. You can pass in any value accepted by the `zf-cell()` mixin, such as `6`, `50%`, or `1 of 2`. +/// @param {Number|List} $n - Size to offset by. You can pass in any value accepted by the `xy-cell()` mixin, such as `6`, `50%`, or `1 of 2`. /// @param {Number|Map} $gutters [$grid-margin-gutters] Map of gutters or single value to use for responsive gutters. /// @param {Keyword} $gutter-type [margin] The type of gutter to use. Can be `margin` or `padding` -/// @param {Number|Array|Keyword} $breakpoint [$-zf-zero-breakpoint] - Single value, breakpoint name, or list of breakpoint names to use for `$gutters`. See `-zf-breakpoint-value()`. +/// @param {Number|Array|Keyword} $breakpoint [null] - Breakpoint to use for `$gutters`. It can be a breakpoint name, list of breakpoints or `auto` for all breakpoints. If a list is given, media-queries will be generated. If using with the `breakpoint()` mixin this will be set automatically unless manually entered. /// @param {Boolean} $vertical [false] Sets the direction of the offset. If set to true will apply margin-top instead. @mixin xy-cell-offset( $n, $gutters: $grid-margin-gutters, $gutter-type: margin, - $breakpoint: $-zf-zero-breakpoint, + $breakpoint: null, $vertical: false ) { + $breakpoint: -zf-current-breakpoint($breakpoint, $default: $-zf-zero-breakpoint); $direction: if($vertical, 'top', $global-left); - @include -zf-breakpoint-value($breakpoint, $gutters) { - $gutter: rem-calc($-zf-bp-value) / 2; - $gutter-margin: if($gutter-type == 'margin', $gutter, 0); - $size: if($gutter-margin == 0, #{xy-cell-size($n)}, calc(#{xy-cell-size($n)} + #{$gutter-margin})); - - margin-#{$direction}: #{$size}; + @include -zf-each-breakpoint-in($breakpoint, $media-queries: 'for-lists') { + $offset: xy-cell-offset($n, $gutters, $gutter-type); + margin-#{$direction}: #{$offset}; } } diff --git a/test/sass/_selector.scss b/test/sass/_selector.scss index 8e47ae7caf..9385f06dc5 100755 --- a/test/sass/_selector.scss +++ b/test/sass/_selector.scss @@ -3,13 +3,11 @@ @import '../../scss/util/selector'; @include test-module('Selector') { - + @include test('Selector [function]') { $test: #{text-inputs(text password)}; $expect: "[type='text'], [type='password']"; - //@debug $test; - @include assert-equal($test, $expect, 'Creates a selector out of a list of text input types'); } @@ -18,8 +16,6 @@ $test: #{text-inputs(text password, $modifier: ':focus')}; $expect: "[type='text']:focus, [type='password']:focus"; - //@debug $test; - @include assert-equal($test, $expect, 'Creates a selector out of a list of text input types with a modifier'); }