I wish to make a mixin to produce the following result of modifier classes:
.text-left {
text-align: left
}
.text-right {
text-align: right
}
.text-center {
text-align: center
}
.text-justify {
text-align: justify
}
.float-left {
float: left
}
.float-right {
float: right
}
.float-none {
float: none
}
.hide {
visibility: hidden;
overflow: hidden;
max-height: 0
}
.remove {
display: none
}
@media screen and (max-width: 480px) {
.m-text-left {
text-align: left
}
.m-text-right {
text-align: right
}
.m-text-center {
text-align: center
}
.m-text-justify {
text-align: justify
}
.m-float-left {
float: left
}
.m-float-right {
float: right
}
.m-float-none {
float: none
}
.m-hide {
visibility: hidden;
overflow: hidden;
max-height: 0
}
.m-remove {
display: none
}
}
@media screen and (min-width: 481px) and (max-width: 620px) {
.p-text-left {
text-align: left
}
.p-text-right {
text-align: right
}
.p-text-center {
text-align: center
}
.p-text-justify {
text-align: justify
}
.p-float-left {
float: left
}
.p-float-right {
float: right
}
.p-float-none {
float: none
}
.p-hide {
visibility: hidden;
overflow: hidden;
max-height: 0
}
.p-remove {
display: none
}
}
@media screen and (min-width: 621px) and (max-width: 955px) {
.t-text-left {
text-align: left
}
.t-text-right {
text-align: right
}
.t-text-center {
text-align: center
}
.t-text-justify {
text-align: justify
}
.t-float-left {
float: left
}
.t-float-right {
float: right
}
.t-float-none {
float: none
}
.t-hide {
visibility: hidden;
overflow: hidden;
max-height: 0
}
.t-remove {
display: none
}
}
@media screen and (min-width: 956px) and (max-width: 1199px) {
.l-text-left {
text-align: left
}
.l-text-right {
text-align: right
}
.l-text-center {
text-align: center
}
.l-text-justify {
text-align: justify
}
.l-float-left {
float: left
}
.l-float-right {
float: right
}
.l-float-none {
float: none
}
.l-hide {
visibility: hidden;
overflow: hidden;
max-height: 0
}
.l-remove {
display: none
}
}
@media screen and (min-width: 1200px) {
.d-text-left {
text-align: left
}
.d-text-right {
text-align: right
}
.d-text-center {
text-align: center
}
.d-text-justify {
text-align: justify
}
.d-float-left {
float: left
}
.d-float-right {
float: right
}
.d-float-none {
float: none
}
.d-hide {
visibility: hidden;
overflow: hidden;
max-height: 0
}
.d-remove {
display: none
}
}
I came up with this mixin, which depends on the media mixin from Neat by thoughtbot.
@mixin respond($responsive-classes) {
@each $responsive-class in $responsive-classes {
@each $selector, $rules in $responsive-class {
$screen: null;
@if (type-of($rules) == "list") {
@each $rule in $rules {
@include rule-loop($screen, $selector, $rule);
}
} @else {
@include rule-loop($screen, $selector, $rules);
}
}
}
@each $screen, $query in (
m: max-width $small-screen, // Phones
p: min-width $small-screen + 1 max-width $medium-screen, // Phones to Phablets
t: min-width $medium-screen + 1 max-width $large-screen, // Phablets to Tablets
l: min-width $large-screen + 1 max-width $wide-screen - 1, // Tablets to Desktops
d: min-width $wide-screen) { // Desktops
@include media($query, $grid-columns) {
@each $responsive-class in $responsive-classes {
@each $selector, $rules in $responsive-class {
@if (type-of($rules) == "list") {
@each $rule in $rules {
@include rule-loop($screen, $selector, $rule);
}
} @else {
@include rule-loop($screen, $selector, $rules);
}
}
}
}
}
}
@mixin rule-loop($screen, $selector, $rules) {
@each $property, $values in $rules {
$list: false;
@if (type-of($values) == "list") { $list: true; }
@include value-loop($values, $screen, $selector, $property, $list);
}
}
@mixin value-loop($values, $screen, $selector, $property, $list) {
@each $value in $values {
@if $list {
@if $screen == null {
.#{$selector}-#{$value} {
#{$property}: #{$value};
}
} @else {
.#{$screen}-#{$selector}-#{$value} {
#{$property}: #{$value};
}
}
} @else {
@if $screen == null {
.#{$selector} {
#{$property}: #{$value};
}
} @else {
.#{$screen}-#{$selector} {
#{$property}: #{$value};
}
}
}
}
}
This is how I call it:
@include respond((
(text: (text-align: (left, right, center, justify))),
(float: (float: (left, right, none))),
(hide: ((visibility: hidden), (overflow: hidden), (max-height: 0))),
(remove: (display: none))
));
It got way too complex at some point and I believe it's quite wet. Perhaps someone would be able to dry it out, or have me make a more dry approach to produce the same results? I need the mixin to be dynamic in order to be able to produce more modifier classes, should I need to do so, in the future.
The grid variables are as follows:
// Grid system
$grid-columns: 12;
$sidebar-columns: 4;
$max-width: 1170px;
// Breakpoints
$small-screen: 480px;
$medium-screen: 620px;
$large-screen: 955px;
$wide-screen: 1200px;
You may use #{$query}
instead of media($query, $grid-columns)
without the Neat mixin. I only used it so that the media queries would combine.
*-screen
variables and themedia
mixin. Tried on SassMeister. \$\endgroup\$ – fracz Jun 12 '16 at 13:09