How to reference nested scss class within media query? - sass

I have media query used in scss class, I would like to create media query and define all scss class in that media query. I have trouble accessing nested scss class in media query.
Here is my code
.data-one {
display: flex;
flex-wrap: wrap;
&.mobile {
width: 100%;
.data {
max-width: 100%;
}
}
.data {
height: 72px;
margin-right: 10px;
max-width: 224px;
// #media (max-width: layout-breakpoint-tablet-start) { -----------> This is the original code
// display: none;
// }
}
}
This is what I have tried but it is not working as expected
#media (max-width: layout-breakpoint-tablet-start) {
.data-one {
+.data {
display: none;
}
}
}

Sass 3.2 added the #content directive, which allows us to pass a content block into a mixin as following:
#mixin screen($size) {
$desktop: "(min-width: 1024px)";
$tablet: "(min-width: 768px) and (max-width: 1023px)";
$mobile: "(max-width: 767px)";
#if $size == desktop {
#media only screen and #{$desktop} {
#content;
}
}
#else if $size == tablet {
#media only screen and #{$tablet} {
#content;
}
}
#else if $size == mobile {
#media only screen and #{$mobile} {
#content;
}
}
#else {
#media only screen and #{$size} {
#content;
}
}
}
.wrapper {
margin: 0 auto;
width: 100%;
#include screen('tablet') {
width: 90%;
}
#include screen('desktop') {
width: 85%;
}
}
If you have any question about it feel free to ask.

Related

Is there a way to write style that will always come after mixins are included?

I am facing a problem with the SCSS mixins whereby I have to repeat the same code to get the work done. I have the following SCSS code:
#mixin column($count, $size) { // Can not make any change in this code.
width: getWidth($count, $size);
margin-left: 3%;
margin-right: 3%;
}
#mixin desktop {
#media screen and (min-width: 1024px) {
#content;
}
}
#mixin tablet {
#media screen and (min-width: 768px) and (max-width: 1023px) {
#content;
}
}
#function getWidth($count, $size) {
#return 50; // For example purpose only.
}
.c {
#include desktop {
#include column(10, large);
}
#include desktop {
#include column(11, large);
}
margin: 0 auto;
}
which is compiled into:
.c {
margin: 0 auto;
}
#media screen and (min-width: 1024px) {
.c {
width: 50;
margin-left: 3%;
margin-right: 3%;
}
}
#media screen and (min-width: 1024px) {
.c {
width: 50;
margin-left: 3%;
margin-right: 3%;
}
}
The problem here is that margin is overwritten by the mixins. Or I have to repeat the same code(duplicate code) like below:
.c {
#include desktop {
#include column(10, large);
margin: 0 auto; // Duplicate
}
#include desktop {
#include column(11, large);
margin: 0 auto; // Duplicate
}
margin: 0 auto;
}
to get:
.c {
margin: 0 auto;
}
#media screen and (min-width: 1024px) {
.c {
width: 50;
margin-left: 3%;
margin-right: 3%;
margin: 0 auto;
}
}
#media screen and (min-width: 1024px) {
.c {
width: 50;
margin-left: 3%;
margin-right: 3%;
margin: 0 auto;
}
}
Is there any better way to remove this duplicate code so that I have to write code only once?
Try this to see if the #media query comes after makes you happy.
.c {
#include desktop {
#include column(10, large);
}
#include desktop {
#include column(11, large);
}
& {
margin: 0 auto;
}
}

Create hidden classes

I try to take a mixin from bootstrap 4. Unfortunately, there is a mistake that I can not explain.
Here is my SASS code:
$mdc-layout-grid-breakpoints: (
desktop: 840px,
tablet: 480px,
phone: 0px
);
#mixin media-breakpoint-up($name, $breakpoints: $mdc-layout-grid-breakpoints) {
$min: breakpoint-min($name, $breakpoints);
#if $min {
#media (min-width: $min) {
#content;
}
} #else {
#content;
}
}
#each $breakpoint in map-keys($mdc-layout-grid-breakpoints) {
#include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $mdc-layout-grid-breakpoints);
.d#{$infix}-none { display: none !important; }
.d#{$infix}-inline { display: inline !important; }
.d#{$infix}-inline-block { display: inline-block !important; }
.d#{$infix}-block { display: block !important; }
.d#{$infix}-table { display: table !important; }
.d#{$infix}-table-row { display: table-row !important; }
.d#{$infix}-table-cell { display: table-cell !important; }
.d#{$infix}-flex { display: flex !important; }
.d#{$infix}-inline-flex { display: inline-flex !important; }
}
}
The error in the console:
I do not understand the information with the "&".
Error in plugin 'sass'
Message:
src\scss\mixins\_display.scss
Error: Base-level rules cannot contain the parent-selector-referencing character '&'.
Backtrace:
src/scss/mixins/_display.scss:40, in mixin `#content`
src/scss/mixins/_display.scss:29, in mixin `media-breakpoint-up`
src/scss/mixins/_display.scss:37
on line 40 of src/scss/mixins/_display.scss
>> .d#{$infix}-none { display: none !important; }
--------^
I hope for help :-)
It seems that it's hard to determine where the style code starts, and where the selector code ends.
Therefore, such a hack:
.d#{$infix + '-none'} { display: none !important; }

Is there a way to include a mixin as a variable

I just tried to save me some time, generating some helper css classes for different breakpoints.
What I tried:
#mixin resp { width: 100%; height: auto;}
#mixin table { display: table}
#mixin trow { display: table-row}
#mixin tcell { display: table-cell; }
#mixin gutter1px { padding: 0 1px; }
$tools: resp, table, trow, tcell, gutter1px;
#mixin make-tools($breakpoint) {
#each $tool in $tools {
$i: index($tools, $tool);
.#{$tool}-$breakpoint { #include #{$tool}(); }
}
}
#media (min-width: $screen-xs-min) {
#include make-tools(xs);
}
But this dosent seem to work:
#include #{$tool}();
Has anyone an idea how to archive that, or is it simply not possible?

Undefined operation: "500px gte medium-screens"

I'm trying to combine Jake Archibald's mobile-friendly IE sass mixins... http://jakearchibald.github.io/sass-ie ...with the responsive mixins illustrated by Dan Cederholm in his book 'Sass for Web Designers'. I'm using CodeKit to compile the files (detailed below).
all.scss compiles successfully, but all-old-ie.scss fails. CodeKit says:
Error: Undefined operation: "500px gte medium-screens".
on line 8 of /Applications/MAMP/htdocs/sass-ie-test/sass/_utils.scss, in `responsive'
from line 4 of /Applications/MAMP/htdocs/sass-ie-test/sass/_layout.scss
from line 2 of /Applications/MAMP/htdocs/sass-ie-test/sass/all.scss
from line 3 of /Applications/MAMP/htdocs/sass-ie-test/sass/all-old-ie.scss
Use --trace for backtrace.
Not sure what's going on here. My files are:
_utils.scss
$medium: 600px;
$large: 950px;
$fix-mqs: false !default;
#mixin responsive($width) {
#if $fix-mqs {
#if $fix-mqs >= $width {
#content;
}
}
#else if $width == medium-screens {
#media only screen and (min-width: $medium) {
#content;
}
}
#else if $width == large-screens {
#media only screen and (min-width: $large) {
#content;
}
}
}
$old-ie: false !default;
#mixin old-ie {
#if $old-ie {
#content;
}
}
_layout.scss
article {
padding: 30px;
#include responsive(medium-screens) {
padding: 50px;
}
#include responsive(large-screens) {
padding: 70px;
}
#include old-ie {
//stuff for ie
}
}
all.scss
#import 'utils';
#import 'layout';
all-old-ie.scss
$old-ie: true;
$fix-mqs: 500px;
#import 'all';
The error is quite clear here. It explicitly states that it cannot possibly determine whether or not the number 500px is greater than or equal (gte) to the string medium-screens.
You're trying to overcomplicate things for no reason: just use variables.
$medium: 600px;
$large: 950px;
#mixin responsive($width) {
#if $fix-mqs {
#if $fix-mqs >= $width {
#content;
}
} #else {
#media only screen and (min-width: $width) {
#content;
}
}
}
article {
padding: 30px;
#include responsive($medium) {
padding: 50px;
}
#include responsive($large) {
padding: 70px;
}
#include old-ie {
//stuff for ie
}
}

sass code style with media queries

I'm doing a code review for sass code and came across using media queries inside the code. Is it a good practice? Are there better alternatives to writing this code?
.col-md-push-8 {
padding-top: 1.5em;
.btn {
&.btn-block {
border: none;
background-color: $footer-button;
margin: 1em 0 .5em;
width: 100%;
padding: 7px 10px;
border-radius: 8px;
&:hover {
background-color: $footer-button-hover;
}
#media (min-width: $screen-md-min) {
color: #025191;
&:hover .media span p.media-heading {
color: #0070ca;
}
}
}
}
}
Note: The code is for illustration purpose only and is not completely shown here.
I think that what your way to do it is perfectly fine if you're using SASS >= 3.2 (was buggy before).
Just one thing that you could do to define your media queries breakpoints more globally is to create a mixin for that purpose that you will re-use on each element you need responsive.
This way when you have to change let's say your min breakpoint, add another or change your media min-width to max-width, you don't have to do it everywhere.
Some little example assuming you have already defined $screen-md-min and $screen-md-mid :
#mixin custom-media($size) {
#if ($size == $small) {
#media (min-width: $screen-md-min) { #content; }
}
#else if ($size == $middle) {
#media (min-width: $screen-md-mid) { #content; }
}
}
And call it like so :
.btn {
&.btn-block {
...
#include custom-media($small) {
color: #025191;
&:hover .media span p.media-heading {
color: #0070ca;
}
}
}
}
There is no difference if you put Media Query inside or outside. It just depends on your preffered style.
Style 1
.some-class {
#media (min-width: 700px) {
background: red;
}
}
Style 2
#media (min-width: 700px) {
.some-class {
background: red;
}
}
Both will compile as:
#media (min-width: 700px) {
.some-class {
background: red;
}
}
Sass handles this fine, but that code is going to produce overly qualified selectors and is hardly concise.
There are a number of patterns for writing “better” CSS and Sass, such as BEM, OOCSS, OOCSS + Sass, and SMACSS.
There's also a bunch of great information on Media Queries in Sass that is probably worth a read.

Resources