Created
December 8, 2017 22:49
-
-
Save ksenzee/276d60f3e251b1dfafaf52ed8dbdb0de 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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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; | |
} | |
/// 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); | |
} | |
/// 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 iff 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 iff 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; | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The CSS that's output will look something like this: | |
.my-class { | |
// Regular grid CSS for modern browsers. | |
display: grid; | |
grid-template-rows: auto auto; | |
grid-template-columns: 1fr 1fr 1fr; | |
grid-gap: 3em 1.5em; | |
grid-auto-flow: column; | |
// CSS for IE 10 and 11. | |
display: -ms-grid; | |
-ms-grid-columns: 1fr 1.5em 1fr 1.5em 1fr; | |
-ms-grid-rows: auto 3em auto; | |
} | |
// Because IE doesn't have the "grid-auto-flow" property, these declarations | |
// place each element in its grid cell, skipping cells that are only there | |
// to take the place of the column and row gaps that you define in modern | |
// browsers with the "grid-gap" property. | |
.my-class :nth-child(1) { | |
-ms-grid-column: 1; | |
-ms-grid-row: 1; } | |
.my-class :nth-child(2) { | |
-ms-grid-column: 1; | |
-ms-grid-row: 3; } | |
.my-class :nth-child(3) { | |
-ms-grid-column: 3; | |
-ms-grid-row: 1; } | |
.my-class :nth-child(4) { | |
-ms-grid-column: 3; | |
-ms-grid-row: 3; } | |
.my-class :nth-child(5) { | |
-ms-grid-column: 5; | |
-ms-grid-row: 1; } | |
.my-class :nth-child(6) { | |
-ms-grid-column: 5; | |
-ms-grid-row: 3; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import "grid_mixins"; | |
// Usage example: | |
// This will create a 2-row, 3-column grid, with 1.5em gaps between | |
// the columns and 3em gaps between the rows. | |
.my-class { | |
display: grid; | |
display: -ms-grid; | |
@include grid-columns(1.5em, 1fr 1fr 1fr); | |
@include grid-rows(3em, auto auto); | |
@include grid-autoflow((autoflow: column, columns: 3, rows: 2, gap: both)); | |
} |
This is awesome - thanks! I did notice one small issue, when using this the :nth-child was getting inherited to nested elements. A quick fix for that is to update line 141 & 162 from :nth-child(#{$counter})
to > :nth-child(#{$counter})
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for posting these! In the
grid-columns
andgrid-rows
mixins, I changed@if $gap > 0
to@if $gap >= 0
. Otherwise, if my element already hadgrid-row-gap: 10px;
, then I'd be unable to override that value and change it togrid-row-gap: 0;
via@include grid-rows(0, auto);
. After modifying the mixins, I'm now able to do this. I'm also able to changegrid-template-rows
without affectinggrid-row-gap
via@include grid-rows(-1, auto);
.