Skip to content

Instantly share code, notes, and snippets.

@olets
Last active September 28, 2018 19:03
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 olets/e99c2a0ed632a8d8bafb8e81961f96bd to your computer and use it in GitHub Desktop.
Save olets/e99c2a0ed632a8d8bafb8e81961f96bd to your computer and use it in GitHub Desktop.
Gappy Grid

Gappy Grid is a flexbox grid system for building grids that have equal-width columns, equal-height rows, outer columns flush with the container's sides.

It supports arbitrary column gaps and row gaps, and breakpoint-specific column counts and gap sizes.

It has been tested on the oldest browsers I had handy access to when writing it: Chrome 68, Edge 14, Firefox 61, IE 11, Opera 51, Safari 11, and Safari on iOS 9.

Sassmeister: https://www.sassmeister.com/gist/e99c2a0ed632a8d8bafb8e81961f96bd

Codepen: https://codepen.io/henry/pen/dqYzEW?editors=1100

// ----
// Sass (v3.4.25)
// Compass (v1.0.3)
// ----
// USAGE
// -----
// Markup:
// .target.gappy-grid>.gappy-grid-item*n
//
// Styles
// .target {
// @include gappy-grid(
// <desktop column count>[,
// <tablet column count>[,
// <mobile column count>[,
// <desktop column gap>[,
// <desktop row gap>[,
// <tablet column gap>[,
// <tablet row gap>[,
// <mobile column gap>[,
// <mobile row gap>
// ]]]]]]]])
// }
//
// e.g.
// .gappy-grid-1 {
// @include gappy-grid(5); // column count
// }
//
// .gappy-grid-2 {
// @include gappy-grid(
// 3, 3, 2, // desktop column count, tablet column count, mobile column count
// 2vw // column gap and row gap
// );
// }
//
// .gappy-grid-3 {
// @include gappy-grid(
// 5, 3, 1, // desktop column count, tablet column count, mobile column count
// 40px, 40px, // desktop column gap, desktop row gap
// 20px, 20px, // tablet column gap, tablet row gap
// 10px, 5px // mobile column gap, mobile row gap
// );
// }
//
// Add `.gappy-grid-centered` and `.gappy-grid-right` on the `.grid`
// to control orphan items' alignment.
//
// Note that gappy grids have a bottom margin of -1 * row gap, to
// account for the final row's row gap. If you need bottom margin
// on the grid, it'll probably need a wrapper
$ie_friendly_100_percent: 99.99999%; // there's always one IE problem
$gappy-grid__wide-breakpoint: 1023px !default;
$gappy-grid__narrow-breakpoint: 767px !default;
$gappy-grid__queries: (
medium: '(max-width: #{$gappy-grid__wide-breakpoint})',
narrow: '(max-width: #{$gappy-grid__narrow-breakpoint})'
);
@mixin gappy-grid__media($query) {
@media #{map-get($gappy-grid__queries, $query)} {
@content
}
}
// type functions by Hugo Giraudel
// https://css-tricks.com/snippets/sass/advanced-type-checking/
@function is-number($value) {
@return type-of($value) == 'number';
}
@function is-integer($value) {
@return is-number($value) and round($value) == $value;
}
@mixin gappy-grid-items(
$column-count: 1,
$column-gap: 0,
$row-gap: $column-gap
) {
> .gappy-grid-item {
@if $column-gap > 0 {
width: calc(((#{$ie_friendly_100_percent} + #{$column-gap}) / #{$column-count}) - #{$column-gap});
} @else {
width: calc(#{$ie_friendly_100_percent} / #{$column-count})
}
@if $row-gap > 0 {
margin-bottom: $row-gap;
}
@if $column-gap > 0 {
&:nth-child(n) {
margin-right: calc(#{$column-gap});
}
}
&:nth-child(#{$column-count}n),
&:last-child {
margin-right: 0;
}
}
}
@mixin gappy-grid-columns(
$column-count: 1,
$column-gap: 0,
$row-gap: $column-gap,
$query: false
) {
@if $query {
@include media($query) {
@include gappy-grid-items(
$column-count,
$column-gap,
$row-gap
);
}
} @else {
@include gappy-grid-items(
$column-count,
$column-gap,
$row-gap
);
}
}
@mixin gappy-grid(
$desktop-column-count: 0,
$tablet-column-count: $desktop-column-count,
$mobile-column-count: $tablet-column-count,
$desktop-column-gap: 0,
$desktop-row-gap: $desktop-column-gap,
$tablet-column-gap: $desktop-column-gap,
$tablet-row-gap: $desktop-row-gap,
$mobile-column-gap: $tablet-column-gap,
$mobile-row-gap: $tablet-row-gap
) {
@if $desktop-column-count > 0 and is-integer($desktop-column-count) {
@include gappy-grid-columns(
$desktop-column-count,
$desktop-column-gap,
$desktop-row-gap
);
}
@if ($tablet-column-count != $desktop-column-count or $tablet-column-gap != $desktop-column-gap or $tablet-row-gap != $desktop-row-gap)
and $tablet-column-count > 0
and is-integer($tablet-column-count)
{
@include gappy-grid-columns(
$tablet-column-count,
$tablet-column-gap,
$tablet-row-gap,
tablet-down
);
}
@if ($mobile-column-count != $tablet-column-count or $mobile-column-gap != $tablet-column-gap or $mobile-row-gap != $tablet-row-gap)
and $mobile-column-count > 0
and is-integer($mobile-column-count)
{
@include gappy-grid-columns(
$mobile-column-count,
$mobile-column-gap,
$mobile-row-gap,
mobile
);
}
@if $desktop-row-gap > 0 {
margin-bottom: -#{$desktop-row-gap};
}
@if $tablet-row-gap > 0 and $tablet-row-gap != $desktop-row-gap {
@include media(tablet) {
margin-bottom: -#{$tablet-row-gap};
}
}
@if $mobile-row-gap > 0 and $mobile-row-gap != $tablet-row-gap {
@include media(mobile) {
margin-bottom: -#{$mobile-row-gap};
}
}
}
.gappy-grid {
display: flex;
flex-wrap: wrap;
&.gappy-grid-center {
justify-content: center;
}
&.gappy-grid-right {
justify-content: flex-end;
}
}
<p><em>Gappy Grid</em> is a flexbox grid system for building grids that have equal-width columns, equal-height rows, outer columns flush with the container&#39;s sides.</p>
<p>It supports arbitrary column gaps and row gaps, and breakpoint-specific column counts and gap sizes.</p>
<p>It has been tested on the oldest browsers I had handy access to when writing it: Chrome 68, Edge 14, Firefox 61, IE 11, Opera 51, Safari 11, and Safari on iOS 9.</p>
<p>Sassmeister: <a href="https://www.sassmeister.com/gist/e99c2a0ed632a8d8bafb8e81961f96bd">https://www.sassmeister.com/gist/e99c2a0ed632a8d8bafb8e81961f96bd</a></p>
<p>Codepen: <a href="https://codepen.io/henry/pen/dqYzEW?editors=1100">https://codepen.io/henry/pen/dqYzEW?editors=1100</a></p>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment