Skip to content

Instantly share code, notes, and snippets.

@johnhunter
Forked from ksenzee/grid_mixins.scss
Last active January 29, 2019 08:35
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 johnhunter/1c7d332e7c2ed8351e36c40695b94d4f to your computer and use it in GitHub Desktop.
Save johnhunter/1c7d332e7c2ed8351e36c40695b94d4f to your computer and use it in GitHub Desktop.
Mixins that make it possible to use CSS Grid in IE 10/11 as well as in modern browsers. Based on mixins by Sascha Fuchs at https://medium.com/@gisugosu/css-grid-layout-spec-2-to-spec-1-transpiler-with-sass-415dff4dd31b.
//
// Grid mixins to support IE11
// https://gist.github.com/johnhunter/1c7d332e7c2ed8351e36c40695b94d4f
//
/// Add Gap between the boxes
///
/// @author Sascha Fuchs
///
/// @group core - cssgrid
///
/// @param {list} $boxes - List with box sizes
/// @param {string} $gap - Optional column gap
@function box-gap($boxes, $gap) {
$box: ();
@for $i from 1 through length($boxes) {
$box: append($box, nth($boxes, $i), space);
// Adding Gap Between
@if $gap > 0 {
// Not last Loop
@if $i != length($boxes) {
$box: append($box, $gap, space);
}
}
}
@return $box;
}
/// Helper for repeating col/row values
///
/// @author John Hunter
///
/// @param {number} $count - number of times to repeat
/// @param {string} $value - value to repeat, default 1fr
@function grid-repeat($count, $value: 1fr) {
$list: ();
@for $i from 1 through $count {
$list: append($list, $value, space);
}
@return $list;
}
/// The basic grid container
@mixin display-grid {
display: -ms-grid;
display: grid;
}
/// To build Grid Template Columns with optional gap
///
/// @author Sascha Fuchs
///
/// @group core - cssgrid
///
/// @param {string} $gap - Optional column gap
/// @param {list} $columns - Columns sizes
///
/// @require {function} box-gap
///
/// @example scss - scss
/// .test {
/// @include grid-columns(10px 250px 1fr 50px 100px);
/// }
@mixin grid-columns($gap, $columns) {
grid-template-columns: $columns;
@if $gap > 0 {
grid-column-gap: $gap;
}
-ms-grid-columns: box-gap($columns, $gap);
}
/// To build Grid Template Rows with optional gap
///
/// @author Sascha Fuchs
///
/// @group core - cssgrid
///
/// @param {string} $gap - Optional row gap
/// @param {list} $rows - Rows sizes
///
/// @require {function} box-gap
///
/// @example scss - scss
/// .test {
/// @include grid-rows(10px 1fr);
/// }
@mixin grid-rows($gap, $rows) {
grid-template-rows: $rows;
@if $gap > 0 {
grid-row-gap: $gap;
}
-ms-grid-rows: box-gap($rows, $gap);
}
/// Set grid-column for individual column
///
/// @author John Hunter
///
/// @param {number} $col-start
/// @param {number} $col-end
///
@mixin grid-column($col-start, $col-end) {
-ms-grid-column: $col-start;
-ms-grid-column-span: $col-end - $col-start;
grid-column: #{$col-start} / #{$col-end};
}
/// Set grid-row for individual row
///
/// @author John Hunter
///
/// @param {number} $col-start
/// @param {number} $col-end
///
@mixin grid-row($row-start, $row-end) {
-ms-grid-row: $row-start;
-ms-grid-row-span: $row-end - $row-start;
grid-row: #{$row-start} / #{$row-end};
}
/// Generates IE10/11 grid placement to simulate grid-auto-flow.
///
/// @author Katherine Senzee
///
/// @param {map} $data - Information needed to tell IE exactly where to place everything.
/// @param {string} $data.autoflow - value for "grid-auto-flow". Either 'column' or 'row'.
/// @param {number} $data.columns - number of columns in the grid
/// @param {number} $data.rows - number of rows in the grid
/// @param {string} $data.gap - Where to allow for gaps. Should be 'column', 'row', or 'both'.
///
/// @example scss -
/// .quotes {
/// @include grid-autoflow(autoflow: column, columns: 3, rows: 6, gap: both);
/// }
@mixin grid-autoflow($data) {
$autoflow: map-get($data, autoflow);
$columns: map-get($data, columns);
$rows: map-get($data, rows);
$columnGap: false;
$rowGap: false;
@if (map-get($data, 'gap') == 'column') {
$columnGap: true;
$rowGap: false;
}
@else if (map-get($data, gap) == 'row') {
$columnGap: false;
$rowGap: true;
}
@else if (map-get($data, gap) == 'both') {
$columnGap: true;
$rowGap: true;
}
@else if (map-get($data, gap) == 'neither') {
$columnGap: false;
$rowGap: false;
}
@else {
@error "The 'gap' argument must be one of 'column', 'row', 'both', or 'neither'";
}
@if ($columnGap) {
$columns: $columns * 2 - 1;
}
@if ($rowGap) {
$rows: $rows * 2 - 1;
}
grid-auto-flow: $autoflow;
$column: 1;
$row: 1;
$counter: 1;
@if ($autoflow == 'column') {
@for $i from 1 through $columns {
@for $j from 1 through $rows {
// This element can be filled if we are not in a row gap or a column gap.
@if ($i % 2 == 0 and $columnGap) {
// This is a column gap. Don't place the next element.
}
@else if ($j % 2 == 0 and $rowGap) {
// This is a row gap. Don't place the next element.
}
@else {
// Place the next element in column $i and row $j.
> :nth-child(#{$counter}) {
-ms-grid-column: $i;
-ms-grid-row: $j;
}
$counter: $counter + 1;
}
}
}
}
@else if ($autoflow == 'row') {
@for $i from 1 through $rows {
@for $j from 1 through $columns {
// This element can be filled if we are not in a row gap or a column gap.
@if ($i % 2 == 0 and $rowGap) {
// This is a row gap. Don't place the next element.
}
@else if ($j % 2 == 0 and $columnGap) {
// This is a column gap. Don't place the next element.
}
@else {
// Place the next element in row $i and column $j.
> :nth-child(#{$counter}) {
-ms-grid-column: $j;
-ms-grid-row: $i;
}
$counter: $counter + 1;
}
}
}
}
}
@import "grid_mixins";
$unit: 8px;
$unitx2: $unit * 2;
// Usage example:
.grid {
@include display-grid;
// Note: must include all grid elements otherwise IE11 will place implicit
// elements over the explicit grid at position 0,0
$cols: 2;
$rows: 4;
// 2-row, 3-column grid with $unit gap
@include grid-columns($unit, grid-repeat($cols, 1fr));
@include grid-rows($unit, grid-repeat($rows, min-content));
@include grid-autoflow((
autoflow: row,
columns: $cols,
rows: $rows,
gap: both
));
> div {
padding: $unitx2;
}
}
.cellSmall {
background-color: map-get($clover, '200');
}
.cellMed {
background-color: map-get($desert, '200');
}
.cellLrg {
// Note: Cannot override IE11 positioning defined in @include grid-autoflow
// as it generates hard-coded rcol/row positions for elements.
@include grid-column(1, 3);
background-color: white;
}
@johnhunter
Copy link
Author

Updated as per upstream comment

@johnhunter
Copy link
Author

Added repeat function and display-grid mixin

@johnhunter
Copy link
Author

Add grid-column and grid-row mixins

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment