Skip to content

Instantly share code, notes, and snippets.

@manuhabitela
Last active January 11, 2021 14:15
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save manuhabitela/608d15fbacc95976f96d to your computer and use it in GitHub Desktop.
Save manuhabitela/608d15fbacc95976f96d to your computer and use it in GitHub Desktop.
Making the Bootstrap grid with Susy and sass-mq
// this is (a start of) an example of a Susy+mq() setup that mimics bootstrap grid.
// I work on multiple bootstrap-based projects.
// I want to stop using grid classes in the markup, and start using mixins with susy and sass-mq.
// Since the project is heavily tied to the bootstrap grid, I want to have the exact same behavior
// between bootstrap classes (old code) and susy mixins (new code).
// all the grid classes generated below are here to ease up testing.
// required: susy + sass-mq
// @todo:
// * handle offsets
// * verify if nesting works good
// * add some easy-to-use mixins
$susy-columns: 12;
$susy-gutter-width: 15px;
$susy: (
columns: $susy-columns,
gutter-position: inside-static, //fixed width gutters like bootstrap
//it seems we *have* to set the column width in order to get static gutters
// but it is not taken into account when using the span mixin. Must miss something...
column-width: 120px,
gutter: $susy-gutter-width/120px
);
// bootstrap compatible breakpoints
// choose the names you want!
$mq-breakpoints: (
tablet: 768px,
desktop: 992px,
wide: 1200px,
);
// common styling applied to any column (class="col-*" in bootstrap)
// /!\ you should not use this directly and see the column mixin
%columnDefaultStyles {
box-sizing: border-box;
position: relative;
float: left;
padding-left: $susy-gutter-width;
padding-right: $susy-gutter-width;
}
// common styling applied to any row (class="row" in bootstrap)
// /!\ you should not use this directly and see the row mixin
%rowDefaultStyles {
@include break;
@include susy-clearfix;
margin-left: -$susy-gutter-width;
margin-right: -$susy-gutter-width;
}
/// set something to behave as a row (like having a class="row" on your element in a bootstrap project)
@mixin row() {
@extend %rowDefaultStyles;
}
/// pass a map of [sass-mq compatible breakpoint:column width] to define responsive column sizes
/// this kinda matches bootstrap columns, and allows for more breakpoints if we want
/// Instead of writing `<div class="col-xs-12 col-md-6 col-lg-3">` in your HTML,
/// write `@include column((small: 12, desktop: 6, wide: 3))` in your Sass
@mixin column($widthList) {
@extend %columnDefaultStyles;
@each $breakpoint, $width in $widthList {
@if ($breakpoint == small) {
width: span($width of $susy-columns);
} @else {
@include mq($from: $breakpoint) {
width: span($width of $susy-columns);
}
}
}
}
//////////////////////////////
// example!
//
// `<div class="MyComponent-wrapper">
// <div class="MyComponent-child"></div>
// <div class="MyComponent-child"></div>
// <div class="MyComponent-child"></div>
// </div>`
// .MyComponent-wrapper {
// @include row;
// }
// .MyComponent-child {
// @include column( (small: 12, tablet: 4, wide: 2) );
// }
//
// is the same as:
// `<div class="MyComponent-wrapper row">
// <div class="MyComponent-child col-xs-12 col-md-4 col-lg-2"></div>
// <div class="MyComponent-child col-xs-12 col-md-4 col-lg-2"></div>
// <div class="MyComponent-child col-xs-12 col-md-4 col-lg-2"></div>
// </div>`
///////////////////////////////
// this is made only to easily test if our code is working correctly when copy/pasting some bootstrap html code
// in the real world this is unnecessary
@mixin make-bootstrap-breakpoint-classes($class) {
@for $i from 1 through $susy-columns {
.col-#{$class}-#{$i} {
width: span($i of $susy-columns);
}
}
}
@mixin make-bootstrap-classes() {
.row {
@include row();
}
$list: ".col-xs-1, .col-sm-1, .col-md-1, .col-lg-1";
@for $i from 2 through $susy-columns {
$list: "#{$list}, .col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}";
}
#{$list} {
@extend %columnDefaultStyles;
}
@include make-bootstrap-breakpoint-classes('xs');
@include mq($from: tablet) {
@include make-bootstrap-breakpoint-classes('sm');
}
@include mq($from: desktop) {
@include make-bootstrap-breakpoint-classes('md');
}
@include mq($from: wide) {
@include make-bootstrap-breakpoint-classes('lg');
}
}
// if you want the exact same thing as bootstrap,
// you will need to insert their "scaffolding code"
// (normalize.css + default stylings on body, html, etc.)
@include make-bootstrap-classes();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment