Is it possible to render arbitrary strings in scss? You can render property values:
/*source scss*/
$some-color: #123456;
a {color: $some-color;}
/*compiled css*/
a {color: #123456;}
or selectors/property names using #{} interpolation syntax:
/*source scss*/
$some-class: 'my-awesome-link';
$some-attribute: border;
a.#{$some-class} {#{$some-attribute}-color: #000;}
/*compiled css*/
a.my-awesome-link {border-color: #000;}
but I can't use the following:
/*source scss*/
$some-css: 'text-decoration:none;color:#000';
a {$some-css} //breaks
a {#{$some-css}} //breaks
This seems like vanilla string processing and something extremely trivial to allow. Am I overlooking a different syntax, or is it not possible in current scss?
The closest you can get to what you want is like this:
#mixin property-list($list) {
#each $i in $list {
#{nth($i, 1)}: nth($i, 2);
}
}
$links: color red, border (1px solid);
a {
#include property-list($links);
}
Compiles to:
a {
color: red;
border: 1px solid;
}
Related
Is it possible to manipulate with #content magic variable in SASS?
I would like to replace some stuff in here before output.
Or maybe can I fill some variable with it?
The conclusion is that, I want to make an mixin #important that create both versions. Important, and no-important.
Input
.test {
#include important {
color: red;
text-align: left;
}
}
Expected output
.test {
color: red;
text-align: left;
}
.test-i {
color: red !important;
text-align: left !important;
}
No, you can't. But I quickly wrote you a mixin to make it work. It doesn't accepts multiple properties (yet).
First Note: I changed the mixin it now does accept multiple properties. Here is the Codepen.
Second Note: I updated the mixin adding multiple properties does no longer compile to different classes for each property, instead you get two versions, one without the !important suffix and one with.
This is the mixin:
#function return($state) {
#return if($state == '', '', '-i');
}
#mixin loop($name, $items...) {
#each $item in $items / 2 {
#each $state in ('', '!important') {
$suffix: return($state);
.#{$name}#{$suffix} {
#for $i from 1 through (length($items) / 2) {
#{nth($items, ($i * 2) - 1)}: #{nth($items, ($i * 2))} #{$state};
}
}
}
}
}
This is how you include it:
// #include loop([classname], [property], [value]);
#include loop(whateverClassname, color, red);
This is what it compiles to:
.whateverClassname {
color: red ;
}
.whateverClassname-i {
color: red !important;
}
This is what it now compiles to, when you use multiple properties at once:
#include loop(whateverClassname, color, red, background-color, green, display, flex);
.whateverClassname {
color: red ;
background-color: green ;
display: flex ;
}
.whateverClassname-i {
color: red !important;
background-color: green !important;
display: flex !important;
}
Conclusion: it works as expected and does no longer bloat your CSS.
Hope I could help you at least a little ;-)
Another problem here.. my team wants to use borders in different widths, colors and positions. So, I made this:
$position-list: top right bottom left;
$colors-list: fff ccc ddd eee;
#for $i from 1 through 3 {
#each $position in $position-list {
#each $color in $colors-list {
.border-#{$position}-#{$i}-#{$color} {
border-#{$position}: #{$i}px solid #{"#"}#{$color} !important;
}
}
}
}
This works great, however, I want to include the colors as variables from my colors.scss sheet ($light-color, $dark-color etc). The problem is that the hashtags from the colors.scss sheet will be transfered as well ($dark-color: #000), so it will most likely generate a weird selector (.border-top-1-#000) or doesn't compile at all.
Is there a way of stripping the variables from the colors.scss sheet of their hashtags before putting them in the selector? Or does anyone have a different/better approach?
We can convert the color to a string (#inspect) and slice it (#str-slice).
$dark-color: #000;
$light-color: #fff;
$abc-color: #abc;
$position-list: top right bottom left;
$colors-list: $dark-color $light-color $abc-color;
#for $i from 1 through 3 {
#each $position in $position-list {
#each $color in $colors-list {
$stripped-color: str-slice(inspect($color), 2);
.border-#{$position}-#{$i}-#{$stripped-color} {
border-#{$position}: #{$i}px solid #{$color} !important;
}
}
}
}
Output (example):
.border-top-1-abc {
border-top: 1px solid #abc !important;
}
Can I somehow make use of a static class inside sass to style child elements based on a color variable defined?
Let's say I have a class named red, and I want to define a variable called $color: classname; or $color: #ff0000; based on that class.
If class is red then define an existing variable with a custom color so I can reuse that variable everywhere inside my scss files based on what class I have on the container.
Note that I have a limited number of colors that I need, and can define them inside sass.
Is this what you're looking for?
$colors : (red, blue, green); // array of colors
#each $color in $colors {
.#{$color} {
color: $color;
}
}
The output of the above SASS is
.red {
color: red;
}
.blue {
color: blue;
}
.green {
color: green;
}
If I understand correct your problem You could use a class red and extend this class when you need it.
$red: #FF0000;
.red {
color: $red;
}
.div {
#extend .red;
}
I believe what you are trying to do is:
In an example file called "base.scss":
$red: red;/*this could be a HEX, RGB, whatever*/
#import "other"
In the example file called "other.scss":
div
{
color: $red
}
I've got list of colors and I would like to use darken() on them like so:
$innerPagesBgColors: "#6B46C1", "#2980B9", "#FD5456", "#000";
.foo {
color: darken(nth($innerPagesBgColors, 3), 5%);
}
But I get this error:
$color: "#FD5456" is not a color for `darken'
I tried interpolating the nth() portion but that didn't help either.
The problem is that darken function requires a color as first argument and, instead, you're trying to pass a string.
type-of(#6B46C1); // returns color
type-of("#6B46C1"); // returns string
So you should remove all quotes in $innerPagesBgColors:
$innerPagesBgColors: #6B46C1, #2980B9, #FD5456, #000;
In my case I solved with this.
#each $name, $color in $set_colors{
// check type-of before
#if (type-of($color) == 'color'){
.color-#{$name}{
color: #{$color};
}
.background-#{$name}{
background-color: $color;
&:hover{
background-color: darken($color, 10%);
}
}
}
}
I'm trying to make a SCSS stylesheet easily configurable by defining a set of constants that will be used in a number of mixins and with the Compass library. Ideally, I'd like to be able to do the following:
$item-bgs: linear-gradient(white, black), #ccc;
#mixin some-mixin() {
#include background-with-css2-fallback($item-bgs*);
}
The background-with-css2-fallback is a Compass mixin that accepts up to 10 params. I'm assuming that SASS does not currently support passing a list parameter as the argument list, otherwise Compass would probably use it, but I'm wondering if I can get the $item-bgs list to be the first 2 arguments to the background-with-css2-fallback mixin. Is there a way to do this currently, or is it even planned for SASS in the future?
It may not be supported by SASS natively, but Compass does support passing a list as the first argument to the background-with-css2-fallback mixin. If you look at the source for the mixin, you'll see that it uses a compact function that handles the logic for collapsing the arguments into a single list, whether passed individually or in a single list parameter.
For example, this works fine for me:
#import "compass";
$item-bgs: (linear-gradient(white, black), #ccc);
.test {
#include background-with-css2-fallback($item-bgs);
}
Examples of useing maps as arguments:
Example 1 (list)
#mixin transition($property...){
#if $property {
transition-property: $property;
}
#else {
transition-property: all;
}
transition-timing-function: ease-in-out;
transition-duration: .3s;
transition-delay: 0;
}
.btn {
color: black;
border: 1px solid black;
#include transition(color, border-color);
&:hover {
color: red;
border-color: red;
}
}
Example 2 (Custom params)
#use 'sass:meta';
#mixin example2($args...) {
#each $key, $value in meta.keywords($args) {
#{$key}: #{$value};
}
}
.shape {
#include example2($width:200px, $height:100px);
}
Example 3 (map)
#mixin colors($args:()) {
#if length($colors) > 0 {
#each $key, $val in $args{
.txt-#{$key} {
color: #{$value};
}
.bg-#{$key} {
background-color: #{$value};
}
}
}
}
$colors_map: (
primary: blue,
secondary: green,
accent: red,
light: white,
dark: black
);
#include colors($colors_map);