SASS Loop to output classes with unique number and background-image - css

I've stumbled across a situation where a SASS loop would be great. I have a load of <div>'s, each one has the a unique class that follows the pattern of .band-(number), a simplified version of my HTML would look like this...
<div class="band-1"></div>
<div class="band-2"></div>
<div class="band-3"></div>
etc.
Each of these elements has a unique background-image, but the naming convention of the image follows that of the divs themselves. My CSS needs to output this...
.band-1 {
background-image:url('../img/image_01.png');
}
.band-2 {
background-image:url('../img/image_02.png');
}
.band-3 {
background-image:url('../img/image_03.png');
}
How would I go about outputting this in a concise way? Thanks in advance.

You can solve your problem with a for loop:
#for $i from 1 through 15 {
#if $i < 10 {
.band-#{$i} {
background-image:url("../img/image_0#{$i}.png");
}
} #else {
.band-#{$i} {
background-image:url("../img/image_#{$i}.png");
}
}
}
DEMO

Related

SASS loop to generate chained :not() from variables string

I have a long list of classes I wish to use in a couple of ways.
The list looks something like this (but much longer):
$my-components: '.some-component', '.some-other-component', '.another-component';
One of the ways I need to use this list of class names in SASS (scss), which I can't figure out, is to create a long chained selector of :not()s. The final rendered output should look like this:
.parent {
> * {
&:last-of-type:not(.some-component):not(.some-other-component):not(.another-component):not(etc) {
// style rules
}
}
}
(The goal being to select the last child element of .parent that doesn't have one of the classes in the list).
Question: How can I make the above code DRY by using the $my-components variable?
Note 1: The loop's output needs to be able to be appended to that &:last-of-type, as in above example.
Note 2: I'm using the $my-components variable already in a different function, so I'd like to keep it in the same format if possible.
Note 3: I know this seems hacky and stupid, and that I should just give all of those elements a common shared class instead. But unfortunately I can not currently modify that part of the DOM.
Use a #each loop
scss:
$my-components: '.some-component', '.some-other-component', '.another-component';
.parent {
> * {
$selector: '';
#each $component in $my-components {
$selector: $selector + ":not(#{$component})"
}
&:last-of-type#{$selector} {
color: blue;
}
}
}
css:
.parent > *:last-of-type:not(.some-component):not(.some-other-component):not(.another-component) {
color: blue;
}
What's happening ?
I define a new string variable $selector.
During the #each loop, I'm concatening the string with :not(#{$component}) to add your new selector.

How to concatenate two variables as selector in Less

I'm trying to do something like this
#foo: lorem;
#bar: ipsum;
.#{foo}-#{bar} {
// css-here
}
Expecting result:
.lorem-ipsum {
/** css-here
}
I only found out the Interpolation with one Variable,
.lorem-#{bar} { }
I think I just found the answer, but don't know if it's the best or the only way to do it.
I tried appending & like this
.#{foo}&-#{bar} { ... }
and it worked.

SCSS function with for loop inside not working

I'm trying to write a function that creates a grid layout based on multiple arrangements (as opposed to just the 12 column grid) in Sass (scss syntax). The for loop inside works properly on its own, but when I wrap it in a function it no longer works. I'm new to using Sass functions, so maybe I'm messing up the syntax? Or is this just not possible? I'm just trying to avoid having to write a new for loop for each layout I want to achieve. Thanks in advance.
#function create-grid($num-cols) {
#for $col from 1 through $num-cols {
.col-#{$col}-of-#{$num-cols} {
width: percentage($col / $num-cols);
}
}
}
Sass functions return a value.
If you want to generate css programatically like this, you want to use a mixin.
https://www.sitepoint.com/sass-basics-the-mixin-directive/
#mixin grid($num-cols) {
#for $col from 1 through $num-cols {
.col-#{$col}-of-#{$num-cols} {
width: percentage($col / $num-cols);
}
}
}
#include grid(12)
For anyone who stumbles across this post, the final product is:
#mixin create-grid($num-cols, $col-gutter) {
#for $col from 1 through $num-cols {
.col-#{$col}-of-#{$num-cols} {
width: calc(
((100% - ((#{$num-cols} - 1) * #{$col-gutter})) / #{$num-cols}) *
#{$col} +
((#{$col} - 1) * #{$col-gutter})
);
}
}
}
Thanks a lot to #HorusKol for introducing me to the world of mixins!

CSS - How to select multiple attribute values?

If I have multiple div tags with an attribute containing different numbered values, and I would like to select only number 1 through 10, what is the most efficient way to do this in css?
Is there anything like e.g. .div[line-number=1-10] ?
This is not possible in the standard CSS. It is convenient to use a CSS preprocessor like SASS or LESS which allow you creating loops among many other features. An example with SASS:
$selector: '.div';
#for $i from 1 to 10 {
$selector: $selector + '[line-number=' + $i + ']';
}
#{$selector} {
// style
}
In pure CSS you are doomed to use this solution instead:
.div[line-number=1], .div[line-number=2], .div[line-number=3], .div[line-number=4], .div[line-number=5], .div[line-number=6], .div[line-number=7], .div[line-number=8], .div[line-number=9], .div[line-number=10] {
}
if you have the ability to modify the line-number attribute starting with 0 (01,02,03,04...10) you can do this:
div[line-number^="0"], div[line-number="10"] {
// css properties
}
if not see the answer from #jackBauer
You cannot specify line-number in range (1-10).
This is not available in attribute selector - https://www.w3.org/TR/css3-selectors/#attribute-selectors.
But alternatively you can apply css on each attribute value with something like below
div[line-number="1"] {
color: red;
}
div[line-number="10"] {
color: green;
}
<p>Use attribute selectors</p>
<div line-number="1">one</div>
<div line-number="2">two</div>
<div line-number="10">ten</div>
Hope this will help in some way(y).

Nested pseudoclasses in Less css

I am trying to use LESS CSS to write my CSS but i got a problem with nested pseudoclasses
I
.class1 {
&:nth-of-type(2n) {
.class2{
}
}
}
the output is:
.class1.class2:nth-of-type(2n) {}
but I want to have this:
.class1:nth-of-type(2n) .class2{}
Any ideas?
Not an issue. You probably had a version of LESS CSS that did not produce the correct code. Try the online less converter and see that it works fine. Here is what I get:
(in)
.class1 {
&:nth-of-type(2n) {
.class2{
x:1;
}
}
}
(out)
.class1:nth-of-type(2n) .class2 {
x: 1;
}

Resources