scss mixin linear-gradient, two variables made easy? - sass

I have a list of elements that need some gradient colors. But how can I make a simple mixin that simplifies the whole thing?
For example, in my css I'd like to be able to write:
button { #include linear(blue); }
and then scss would use my mixin and include my colors in my variables
$redTop: #F67777;
$redBottom: #E65050;
$blueTop: #77CFF6;
$blueBottom: #50B9E6;
#mixin linear($color) {
background-image: linear-gradient($colorTop, $colorBottom);
}

For this, you'd want to split the colours into a map.
$red: (
"top": #f00,
"bottom": #c00
);
#mixin linear($color) {
background-image: linear-gradient(map-get($color, "top"), map-get($color, "bottom"));
}
.red-bg {
#include linear($red);
}

Related

Combine raw selector with mixin into single query

I have the following SASS rules:
p {
margin: 0;
}
#include desktop() {
p {
margin: 0;
}
}
The mixin is like this:
#mixin desktop() {
#media screen and (min-width: 1200px) {
#content;
}
}
Elsewhere in the codebase there's a margin being set on desktop, hence in this case I need to explicitly remove it on the desktop breakpoint too, just having the first p selector rule doesn't cut it.
Is there a neat way to combine the selectors as it feels verbose having the same margin: 0 rule twice? I realise there's probably something more fundamentally wrong here with the inheritance, but that's outside the scope of the question. I don't want to use !important.
Many thanks.
Is there a neat way to combine the selectors? Sure there is… Just use another mixin:
#mixin para {
p {
margin: 0;
}
}
#include para;
#include desktop {
#include para;
}
You clearly already know how to use mixins, so I'm assuming your question is really about whether you can nest one mixin within another (yes), or whether you can include selectors within a mixin (yes).

Sass: Setting global variables based on theme

I am trying to set global variables when a theme mixin is included since it seems much more straight-forward to use than this "themify" stuff I find from searching.
The idea is something like having a _themes.scss with
#mixin light-theme { $primary-color: #123456 !global; }
#mixin dark-theme { $primary-color: #654321 !global; }
body.light-theme { #include light-theme }
body.dark-theme { #include dark-theme }
The problem is it always uses the dark-theme value since it is declared last. Is what I am trying to do possible?

Mixin background gradient with background image.png

I have a mixin declared more or less like this
#mixin color-background {
background: yellow;
}
And i would wish to use this color as background of a png. but i cant seem to be able to mix the two
now what i would like to do is for example
.myImageWithBackgroundColor{
background: url(image.png),#include color-background
}
How can i acheive this with SASS and mixin?
You could store the background value of the mixin to a variable, and then use the variable instead of the whole mixin in the second code snippet.
$my-color: yellow;
#mixin color-background {
background: $my-color;
}
.myImageWithBackgroundColor{
background: url(image.png) $my-color;
}

SASS equivalent to LESS Space ("+_") syntax

LESS has a great little feature called Space that allows mixins to append rules to existing properties. Really useful for transform() mixins, because you can append many transform rules to the same property, just by calling the mixin multiple times, eg.
Example:
.scale() {
transform+_: scale(2);
}
.rotate() {
transform+_: rotate(15deg);
}
.myclass {
.scale();
.rotate();
}
Outputs:
.myclass {
transform: scale(2) rotate(15deg);
}
I'm trying to get into SASS, but I don't understand how to achieve this with the available syntax. Whatever I do, the output only ever applies one of the transformations, not both. What is the best way to achieve this behaviour using SASS alone?
You can use variable arguments in a mixin like so:
#mixin transform($transforms...) {
transform: $transforms;
}
.myclass {
#include transform(scale(0.5) rotate(30deg));
}
this will output:
.myclass {
transform: scale(0.5) rotate(30deg);
}
You can see a working example here:
http://codepen.io/sonnyprince/pen/RaMzgb
A little more info:
Sometimes it makes sense for a mixin or function to take an unknown
number of arguments. For example, a mixin for creating box shadows
might take any number of shadows as arguments. For these situations,
Sass supports “variable arguments,” which are arguments at the end of
a mixin or function declaration that take all leftover arguments and
package them up as a list. These arguments look just like normal
arguments, but are followed by ....
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#variable_arguments
Sass does not offer such a feature.
You can get reasonably close by using global variables. However, every single mixin you use, including ones provided by a 3rd party, will have to be modified to work this way.
// the setup
$append-property-vals: (); // global variable
$old-append-property-vals: (); // global variable
#mixin append-property($key, $val, $separator: comma) {
$old-val: map-get($append-property-vals, $key);
#if $old-val {
$append-property-vals: map-merge($append-property-vals, ($key: append($old-val, $val, $separator))) !global;
} #else {
$append-property-vals: map-merge($append-property-vals, ($key: $val)) !global;
}
}
#mixin append-properties {
// cache the original value
$old-append-property-vals: $append-property-vals !global;
#content;
// write out the saved up properties
#each $key, $val in $append-property-vals {
#{$key}: $val;
}
// restore the original value
$append-property-vals: $old-append-property-vals !global;
}
// modify the OP's provided mixins to work
#mixin scale {
// if the vals should be comma delimited, write `comma` instead of `space` for the 3rd argument
#include append-property(transform, scale(2), space);
}
#mixin rotate {
#include append-property(transform, rotate(15deg), space);
}
// call the mixins
.myclass {
#include append-properties {
#include scale;
#include rotate;
}
}
Output:
.myclass {
transform: scale(2) rotate(15deg);
}

What is the equivalent of LESS's "import (reference) 'style'" in SASS

In addition to application.css.scss, I have multiple partials like homepage.css.scss. At the moment I have to add #import 'bootstrap' to each one of them in order to use bootstrap variables and mixins.
Let's say I want to change my default links colour to red, I'd add that to application.css.scss. But the links in homepage.css.scss will not be red because the bootstrap import will override it with blue.
In LESS, I can do #import (reference) "bootstrap", how can I do that in SASS?
The closest you will get is a silent class / placeholder. These work a little different to how LESS and reference work, you can read more on them here: http://blog.teamtreehouse.com/extending-placeholder-selectors-with-sass
LESS
lib.less
.class {
background: red;
}
main.less
#import (reference) "lib";
.anotherClass {
&:extend(.class);
}
SASS
lib.sass
%class {
background: red;
}
main.sass
#import "lib";
.anotherClass {
#extend %class;
}
CSS Output
.anotherClass {
background: red;
}

Resources