Updating a mixin for themes with SASS 3.4.7 - sass

I updated today SASS to use the version 3.4.7 Unfortunetly, one mixin I used since the beginning of my project don't work anymore. I don't understand why...
$program: test1;
#mixin program($programName) {
#each $p in $programName {
#if $p == $program {
#content;
}
}
}
$cta-box-type: null !default;
#include program(test1) {
$cta-box-type: cta-buy, cta-like;
}
#include program(test2) {
$cta-box-type: cta-like, cta-share;
}
#each $cta-type in $cta-box-type {
.banner--#{$cta-type} .banner {
background: white image-url("Modules/Cta/bg-#{$cta-type}-1.jpg") no-repeat bottom left;
background-size: 100% auto;
}
}
DEMO SASSMEISTER
The compiled result looks like this:
.banner-- .banner {
background: white url('/images/Modules/Cta/bg--1.jpg') no-repeat bottom left;
background-size: 100% auto;
}
Instead of:
.banner--cta-buy .banner {
background: white url('/images/Modules/Cta/bg-cta-buy-1.jpg') no-repeat bottom left;
background-size: 100% auto;
}
.banner--cta-like .banner {
background: white url('/images/Modules/Cta/bg-cta-like-1.jpg') no-repeat bottom left;
background-size: 100% auto;
}
If someone have an idea why it's no more working, it's gone help me a lot !
Thanks !

I found the solution :
I simply removed the !default and add !global.
$cta-box-type: null;
#include program(test1) {
$cta-box-type: cta-buy, cta-like !global;
}
#include program(test2) {
$cta-box-type: cta-like, cta-share !global;
}

Related

Can I achieve this versatile mixin in SASS?

I am attempting to reduce the amount of repitition in the following CSS:
$width_altyp_name : 220px;
$width_view_dates : 140px;
$width_alog_status: 60px;
tr,
td {
line-height: 3;
.view_date_raised,
.view_date_sent {
max-width: $width_view_dates;
min-width: $width_view_dates;
}
.altyp_name {
max-width: $width_altyp_name;
min-width: $width_altyp_name;
}
.alog_ID {
max-width: $width_altyp_name;
min-width: $width_altyp_name;
}
.alog_status_text {
max-width: $width_alog_status;
min-width: $width_alog_status;
}
}
I am wondering whether I can use #mixin (or anything else) to produce a "function" which will take 2 arguments:
$classname
$width
and use that to generate CSS rules in the style of the following:
#mixin set-column-width($classname, $width)
$classname {
max-width: $width;
min-width: $width;
}
}
I would hope to then replace much of the above with something like:
#include set-column-width(".view_date_raised", $width_view_dates);
#include set-column-width(".altyp_name", $width_altyp_name);
#include set-column-width(".alog_status_text", $width_alog_status_text);
Thanks to #Arkellys for pointing out that all I needed to do was understand interpolation
My revised SASS is this:
$width_alog_ID : 60px;
$width_alog_status: 60px;
$width_altyp_name : 220px;
$width_emp_names : 150px;
$width_view_dates : 140px;
#mixin set-column-width($c, $w) {
#{$c} {
max-width: $w;
min-width: $w;
}
}
tr,
td {
line-height: 2;
#include set-column-width('.view_date_raised', $width_view_dates);
#include set-column-width('.view_date_sent', $width_view_dates);
#include set-column-width('.altyp_name', $width_altyp_name);
#include set-column-width('.alog_ID', $width_alog_ID);
#include set-column-width('.alog_status_text', $width_alog_status);
#include set-column-width('.emp_drafter', $width_emp_names);
#include set-column-width('.emp_sender', $width_emp_names);
}

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?

Access #mixin variable outside of #mixin

So I've got a #mixinthat lets me define my logo width and gives me an automatic height based on the ratio of my logo image.
#mixin m-logoSize($width) {
width: $width;
height: floor($width / 4.72727272727273);
}
I'm trying to find out if there's a way for me to access the $width variable, so I can assign it to a different property like so.
// sass
.logo {
#include m-logoSize(300px);
background-size: $width $height;
}
// translates to this css
.logo {
width: 300px;
height: 63px;
background-size: 300px 63px;
}
Is there any wizardry that makes this possible. Any help is appreciated.
Thanks in advance!
I think you are better off setting global variables for these two values, then you can reach them anywhere.
Example
// Global variables
$logo-width: 0 !default;
$logo-height: floor($logo-width / 4.72727272727273) !default;
// Mixin
#mixin m-logoSize() {
width: $logo-width;
height: $logo-height;
}
// Sass
$logo-width: 300px;
.logo {
#include m-logoSize();
background-size: $logo-width $logo-height;
}
Update
To change the value at different breakpoints you would just set the variable in the scope of the media query.
Responsive Example
.logo {
#media screen and (max-width: 600px) {
$logo-width: 150px;
#include m-logoSize();
background-size: $logo-width $logo-height;
}
#media screen and (min-width: 601px) {
$logo-width: 300px;
#include m-logoSize();
background-size: $logo-width $logo-height;
}
}

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