One-liner is SASS - css

In CSS I can do something like this:
.apple { background-image: url('apple.png'); }
.orange { background-image: url('orange.png'); }
.pear { background-image: url('pear.png'); }
but it seems in sass (not scss) the same would take up 6 lines? Is it possible to do a one-liner is sass for rules that only have one property?

This isn't by any means meant to help you condense this code to one line, but to think of it from a different perspective.
In this post on The Sass Way titled "Sass control directives: #if, #for, #each and #while", I cover control directives in Sass. Here's a way to write your code using the #each directive.
$fruit-list: apple orange pear
=fruit
#each $fruit in $fruit-list
&.#{$fruit}
background-image: url(#{$fruit}.png)
.fruit
+fruit
Which outputs:
.fruit.apple {
background-image: url(apple.png);
}
.fruit.orange {
background-image: url(orange.png);
}
.fruit.pear {
background-image: url(pear.png);
}
Using .scss we can make this a one liner, but at the cost of readability of the code:
$fruit-list: apple orange pear;
#mixin fruit { #each $fruit in $fruit-list { &.#{$fruit} { background-image: url(#{$fruit}.png); } } }
.fruit { #include fruit; }

Sass syntax is principally based on indentation and line breaks, so in Sass that would indeed be six lines (two per rule, excluding blank lines):
.apple
background-image: url('apple.png')
.orange
background-image: url('orange.png')
.pear
background-image: url('pear.png')
As far as I've seen you can't condense those to one-liners in Sass.

Related

SASS / SCSS: Read file names in a directory

i want to list all *.svg files in a directory, something like this:
// set the folder containing *.svg
$icon-dir: "./my-icon-collection";
// then produces a css like this:
.icon {
.face {
background-image: url("face.svg");
}
.phone{
background-image: url("phone.svg");
}
.message-miss{
background-image: url("message-miss.svg");
}
}
how i write the function/mixin in SASS/SCSS?
I don't think this achievable in a generated css via scss. At the nearest solution is you can get css like this-
generated css image by the below mentioned mixin
$svg-list:"perimter","surface","length","height","width","volume","area";
$icon-dir: "./my-icon-collection/"; // Assuming this is the correct location where all the svg files are placed
#mixin svgPath($svgName) {
.icon {
.#{$svgName} {
background-image: url(#{$icon-dir}#{$svgName}.svg);
}
}
}
#each $svgName in $svg-list {
#include svgPath($svgName);
}

sass mixins and css custom properties

aye folks!
i tried to build a sass mixin for css custom properties to make work a little bit easier.
my attempt does look like this:
#mixin mixin($value) {
background: unquote('$')#{$value};
background: var(--#{$value}, unquote('$')#{$value});
}
the output looks like this:
.example {
background: $value;
background: var(--colour, $value);
}
BUT sass doesn't convert my $value into the actual thing. the $value part end up in my final css file and ofc this doesn't work.
i tried to find a solution online but i'm either to dumb to find it or there isn't one. anyone here has an idea what i'm doing wrong?
I have try your code with this example:
#mixin mixin($value) {
background: unquote('$')#{$value};
background: var(--#{$value}, unquote('$')#{$value});
}
.example {
#include mixin(colour)
}
and it works.
The output is:
.example {
background: $colour;
background: var(--colour, $colour);
}
is what you want? Sorry but I don't have the authorization for add comment so I create this answer.
Edit: you can create a different mixin like this:
#mixin mixin($value, $color) {
background: $color;
background: var(--#{$value}, $color);
}
This help you to solve your problem?

SASS/Compass better organizing

everyone.
I start to learn how to use SASS and Compass and whant to ask advice in better organizing this snippet of code
.main-link.first-item {
#include background(image-url($bg-sprite) no-repeat -27px -39px,
linear-gradient(#4b4e58, #3f424a));
&:hover {
#include background(image-url($bg-sprite) no-repeat -27px -1px,
linear-gradient(#4b4e58, #3f424a));
}
How can I use linear gradient without repeting, but only changing position of image?
You just need to adjust the background position of the first image.
&:hover {
background-position: -27px -1px, 0 0;
}
I agree with #cimmanon's answer.
Although if you want to use the same thing over and over again on different elements in different stylesheets I would propose to create a mixin and put it into a separate sass file. Than you can import that into the files where you need it:
# mixin.css.scss
#mixin custom-background($bg-sprite, $position-vertical, $position-horizontal) {
#include background(image-url($bg-sprite) no-repeat $position-vertical $position-horizontal,
linear-gradient(#4b4e58, #3f424a));
}
# some.css.scss
#import "mixin.css.scss"
.main-link.first-item {
#include custom-background($bg-sprite, -27px, -39px);
&:hover {
#include custom-background($bg-sprite, -27px, -1px);
}
}

SASS checking against a class name

Hi I'm still very new to SASS and no programming guru.
I have ten asides elements that all require different background colours based on their class name.
I've looked through the SASS documentation and I can't figure it out.
I want to say if aside has a class name of x make background colour x if aside has a class name of y make background colour y etc
Is there a nice efficient way of doing this?
Thanks guys and sorry if its a simpleton question.
If you're using colors that don't have "standard" names (or the name of the class isn't going to be the name a color at all, eg. products = blue, addresses = red), a list of lists is what you want:
$colors:
( black #000
, white #FFF
, red #F00
, green #0F0
, blue #00F
);
#each $i in $colors {
aside.#{nth($i, 1)} {
background: nth($i, 2);
}
}
Output:
aside.black {
background: black; }
aside.white {
background: white; }
aside.red {
background: red; }
aside.green {
background: lime; }
aside.blue {
background: blue; }
If you're using colors with standard keywords, this could work:
$colors2: black, white, red, green, blue;
#each $i in $colors2 {
aside.#{$i} { background: $i; }
}
Output (though this only seems to work with --style debug, using --style compress generates errors.. weird):
aside.black {
background: black; }
aside.white {
background: white; }
aside.red {
background: red; }
aside.green {
background: green; }
aside.blue {
background: blue; }
This is simply down to how much typing you want to do. You could make a background mixin and include it within the aside CSS rule, but is that really necessary?
If it is though....
#mixin bg($color) {
background: $color;
}
aside#foo {
#include bg(#fff);
}
"if aside has a class name of x make background colour x if aside has a class name of y make background colour y" translates to the following CSS:
aside.x {background-color: x}
aside.y {background-color: y}
Is there a reason you want to use SASS? Is it to make it dynamic so that you can add any class you want in the future without updating the CSS? (If so that's not possible with SASS because the SASS code compiles to CSS and doesn't change after).
To make that work you'd have to use JS (jQuery):
$('aside').each(function () {
$(this).css('background-color', $(this).attr('class'));
});
Edit: You could use loops in SASS to generate a large number of classes and corresponding background-colors though.

LESS.css variable depending on class

I want to create something like a themepicker. I use LESS.css.
LESS.css has a variable which contains the main colors :
#colorOne: #222;
#colorTwo: #fff;
#darkGradientStart: lighten(#colorOne, 10%);
#darkGradientStop: lighten(#colorOne, 5%);
#lightGradientStart: #colorTwo;
#lightradientStop: darken(#colorTwo, 7%);
I want to change them if the tag has the color-class like this:
<body class='theme-blue'>
then I have written this in my less.css (after the default variables)
.theme-blue{
#colorOne: blue;
}
but it still uses the default #222. It is not overwritten.
How can I solve this problem?
Thanks
You cannot overwrite variables in LESS (within the same scope). The documentation specifically says:
Note that variables in LESS are actually ‘constants’ in that they can only be defined once.
For what you desire, you need to do a mixin:
Example LESS Code
.colorDefs(#c1: #222, #c2: #fff) {
#colorOne: #c1;
#colorTwo: #c2;
#darkGradientStart: lighten(#colorOne, 10%);
#darkGradientStop: lighten(#colorOne, 5%);
#lightGradientStart: #colorTwo;
#lightGradientStop: darken(#colorTwo, 7%);
}
.theme-blue {
//import color definitions
.colorDefs(blue, yellow);
// use them
color: #colorOne;
background-color: #colorTwo;
.gradient1 {
background-image: linear-gradient(top, #darkGradientStart, #darkGradientStop);
}
.gradient1 {
background-image: linear-gradient(top, #lightGradientStart, #lightGradientStop);
}
}
.theme-green {
//import different color definitions
.colorDefs(green, red);
// use them
color: #colorOne;
background-color: #colorTwo;
.gradient1 {
background-image: linear-gradient(top, #darkGradientStart, #darkGradientStop);
}
.gradient1 {
background-image: linear-gradient(top, #lightGradientStart, #lightGradientStop);
}
}
Example CSS Output
.theme-blue {
color: #0000ff;
background-color: #ffff00;
}
.theme-blue .gradient1 {
background-image: linear-gradient(top, #3333ff, #1a1aff);
}
.theme-blue .gradient1 {
background-image: linear-gradient(top, #ffff00, #dbdb00);
}
.theme-green {
color: #008000;
background-color: #ff0000;
}
.theme-green .gradient1 {
background-image: linear-gradient(top, #00b300, #009a00);
}
.theme-green .gradient1 {
background-image: linear-gradient(top, #ff0000, #db0000);
}
Solving 4K (i.e. a lot of) Lines of Code
ed1nh0 commented about having 4K lines of code using the color variables, and not being able to "put that in a mixin." Let me make a few comments on that:
If 4K lines of code depend upon the body class to define the colors, then it is probably best to split each color into its own css file, and only load that file as needed (i.e. not grouping every code color into one file). This then calls into question whether you really want to be controlling color by body class.
Regardless of whether one does what is recommended in 1., I believe one could still handle this with 4K of lines that use the colors. I believe the issue is not in using a mixin to define the color values themselves (i.e. not 4K lines of color variable definitions), but rather in the 4K lines of properties, classes, etc. that need repeating that are using the colors. But that repetition can be handled just as easily by wrapping it all in a mixin also. So my original answer above could be abstracted further to this (note that .colorDefs is the same as above and not repeated here):
LESS
.themeProperties() { // Imagine inside here the 4K lines of code
// use them
color: #colorOne;
background-color: #colorTwo;
.gradient1 {
background-image: linear-gradient(top, #darkGradientStart, #darkGradientStop);
}
.gradient1 {
background-image: linear-gradient(top, #lightGradientStart, #lightGradientStop);
}
}
.theme-blue {
//import color definitions
.colorDefs(blue, yellow);
.themeProperties(); //4K lines repeated here
}
.theme-green {
//import different color definitions
.colorDefs(green, red);
.themeProperties(); //4K lines repeated here
}
The above does assume that there are not differences in how the variables are used by the properties, just what the values of those properties are. If there were any "differences," then some tweaking mixins may need to be done for certain situations, but the concept should still hold.
What you are doing would get compiled like this in css:
.theme-blue{
#222: blue;
}
See why it doesn't work now? :)
If you are trying to override the color style, you should do it the usual css way:
.theme-blue{
color: blue;
}
#blue:#0000FF;
#green:#00FF00;
.theme-blue {
color:#blue;
}
.theme-green {
color:#green;
}

Resources