How to reference previously defined styles - sass

I am new to sass, and I have h1, h2, h3 defined in a .sass file, and I want to do something like the following:
h1 {
font-size: 25px;
}
.section {
h1 { font-size: h1.font-size - 5px; }
}
I know the syntax is incorrect, but I think you get the gist. Would really appreciate it.

You'll have to store the value in a variable:
$h1-font-size: 25px;
h1 {
font-size: $h1-font-size;
.section & {
font-size: $h1-font-size - 5;
}
}
This'll produce the following CSS:
h1 { font-size: 25px; }
.section h1 { font-size: 20px; }

Related

Does SCSS supports arrays in variables?

I have a #mixin for paragraphs that looks like this:
#mixin paragraph {
color: $dark-700;
font-size: 14px;
line-height: 20px;
}
But I was wondering if it's possible to create a $paragraph variable with all those styles in an array or object to call it every time.
I'm not sure I understand your question correctly, but maybe placeholder selectors are what you are looking for:
%paragraph {
color: $dark-700;
font-size: 14px;
line-height: 20px;
}
.section-description {
#extend %paragraph;
}
.banner-text {
#extend %paragraph;
}
More info: https://sass-lang.com/documentation/style-rules/placeholder-selectors

Sass nesting of h1 within a .title selector

I have tried sass
.title {
font-weight: bold;
// more title styles
&h1 {
font-size: 30px;
}
}
Resulting css is:
.titleh1 {
font-weight: bold;
// more title styles
}
.titleh1 {
font-size: 30px;
}
Is there anyway I can keep the h1 nested in the .title to give css output like this?
.titleh1 {
font-weight: bold;
// more title styles
}
h1.title {
font-size: 30px;
}
Yes, you just need the #at-root directive to jump back out of your nested selector:
.title {
font-weight: bold;
// more title styles
#at-root {
h1#{&} {
font-size: 30px;
}
}
}

How to extract common scss code from multiple files?

After converting a lot of redundant crappy css files into scss files, I have a bunch of scss files. I'm pretty sure there is a lot of common css repeated among these files and I would like to extract this code.
As an example, let's say I have this block of scss code (let's call it block A) :
.test {
color: white;
.toto {
background: red;
font-size: 12px;
}
}
And another block (that we'll call block B) :
.test {
color: black;
.toto {
background: blue;
font-size: 12px;
text-align: center;
}
}
I want to be able to extract the following common scss code from block A and B :
.test {
.toto {
font-size: 12px;
}
}
It seems like a simple task to do, but with a large list of long scss files, it's really painful to do it manually. After searching for a while I didn't find any tool for that.
An intermediary solution could be to convert sass code to a multi-dimensionnal associative array and to process arrays to find intersections, but I could not find any simple solution to do that either, so any help would be appreciated.
There are a few approaches but in this instance, I would opt for a variable:
$base-font-size: 12px;
.test {
color: white;
.toto {
background: red;
font-size: $base-font-size;
}
}
.test {
color: black;
.toto {
background: blue;
font-size: $base-font-size;
text-align: center;
}
}
Or you could add a toto mixin with some defaults and use that:
#mixin toto($background: red, $text-align: left, $font-size: 12px) {
.toto {
background: $background;
text-align: $text-align;
font-size: $font-size;
}
}
.test {
color: white;
#include toto();
}
.test {
color: black;
#include toto(blue, center);
}
EDIT: or use extend:
.font-size-12 {
font-size: 12px;
}
.test {
color: white;
.toto {
#extend .font-size-12;
background: red;
}
}
.test {
color: black;
.toto {
#extend .font-size-12;
background: blue;
text-align: center;
}
}

SASS: restrict a rule on tagname

Quite often I need to write something like:
h1, h2, h3, h4, h5, h6 {
font-family: 'myfont';
font-weight: normal;
&.public {
color: $white;
}
}
But I'd like to add a specific rule to h1.public only. Of couse, I could add:
h1.public {
font-size: 2em;
}
but this is because my example is simple and still this is not really DRY. What I'd like is to have it wrapped in my code. Something like:
h1, h2, h3, h4, h5, h6 {
font-family: 'myfont';
font-weight: normal;
&.public {
color: $white;
&:only(h1) {
font-size: 2em;
}
}
}
Just like media queries work.
Is there a way I can do this?
You have different possible approach:
See in live
/* Version 1: with #at-root */
h1 {
#at-root &, h2, h3, h4, h5, h6 {
font-family: 'myfont';
font-weight: normal;
&.public {
color: #FFF;
}
}
&.public {
font-size: 2em;
}
}
/* Version 2: with placeholders */
%org-heading {
font-family: 'myfont';
font-weight: normal;
&.is-public {
color: #FFF;
}
}
#for $i from 1 to 6 {
h#{$i} {
#extend %org-heading;
#if 1 == $i {
&.is-public {
font-size: 2em;
}
}
}
}
/* Version 3: with modular approach */
.org-heading {
font-family: 'myfont';
font-weight: normal;
&--public {
color: #FFF;
&.isFirst {
font-size: 2em;
}
}
}

Incrementing Variable in Loop

I've got the following loop producing some styles for a tag cloud. On the online generators it produces the I'd consider the correct css styles, however in the visual studio solution (2012) which auto produces the css it seems to hang up. (see below) the less. Is there a more proper way to produce something like this via less that won't confuse the VS .less generator?
#iterations: 10;
#maxSize: 40;
#minSize: 10;
.tag-loop (#i) when (#i > -1) {
#j: (#i*(30/#iterations) + #minSize);
li.tag-#{i} {
font-size:~"#{j}px";
}
.tag-loop(#i - 1);
}
.tag-loop (#iterations);
Produces via visual studio:
ul.tag-cloud li.tag-10 {
font-size: 10px;
}
ul.tag-cloud li.tag-9 {
font-size: 10px;
}
ul.tag-cloud li.tag-8 {
font-size: 10px;
}
ul.tag-cloud li.tag-7 {
font-size: 10px;
}
ul.tag-cloud li.tag-6 {
font-size: 10px;
}
ul.tag-cloud li.tag-5 {
font-size: 10px;
}
ul.tag-cloud li.tag-4 {
font-size: 10px;
}
ul.tag-cloud li.tag-3 {
font-size: 10px;
}
ul.tag-cloud li.tag-2 {
font-size: 10px;
}
ul.tag-cloud li.tag-1 {
font-size: 10px;
}
ul.tag-cloud li.tag-0 {
font-size: 10px;
}
If I use something like http://winless.org/online-less-compiler the following is more accurately produced:
li.tag-10 {
font-size: 40px;
}
li.tag-9 {
font-size: 37px;
}
li.tag-8 {
font-size: 34px;
}
li.tag-7 {
font-size: 31px;
}
li.tag-6 {
font-size: 28px;
}
li.tag-5 {
font-size: 25px;
}
li.tag-4 {
font-size: 22px;
}
li.tag-3 {
font-size: 19px;
}
li.tag-2 {
font-size: 16px;
}
li.tag-1 {
font-size: 13px;
}
li.tag-0 {
font-size: 10px;
}
It looks like your VS uses (via Web Essentials 2012?) quite outdated Less 1.3.3 which handles variable scope quite differently, i.e. #j defined in the last iteration overrides all previous #j definitions.
The workaround to this is to calculate font-size value directly:
#iterations: 10;
#maxSize: 40;
#minSize: 10;
.tag-loop (#i) when (#i > -1) {
li.tag-#{i} {
font-size: unit((#i * (30 / #iterations) + #minSize), px);
}
.tag-loop((#i - 1));
}
.tag-loop (#iterations);

Resources