Repeat CSS Style Every Nth Element - css

I am formatting the color of my Atom indent guide lines.
The Atom stylings are in CSS but I can't figure out how to repeat the pattern.
This is what is looks like at moment:
And this is my code:
.editor {
.indent-guide {
// first level
color: rgb(255, 140, 0);
// second level
&:nth-child(2) {
color: rgb(138,43,226);
}
// third level
&:nth-child(3) {
color: rgb(46,139,87);
}
}
}
What is missing?

repetition is missing: you are targeting 2nd and 3rd child only, as exception to the first rule which is applied to all .indent-guide elements.
Use instead 3n + 1 and 3n + 2
.editor {
.indent-guide {
// first level
color: rgb(255, 140, 0);
// second level
&:nth-child(3n + 1) {
color: rgb(138,43,226);
}
// third level
&:nth-child(3n + 2) {
color: rgb(46,139,87);
}
}
}

Related

Classbuilding with scss (double ampersand)

I want to get the following selector B__E.B__E--M so that B__E--M only applies if the element also has the B__E class;
I have the following:
.B {
&__E {
// default color
&--M {
// Color i want
}
}
}
The problem is, that the --M modifier should apply another color, but doesn't overwrite the default color from the __E element.
This is not allowed:
.B {
&__E {
// default color
}
}
.B__E.B__E--M {
// color i want
}
If nothing is possible, this would be my guess:
.B {
&__E {
// default color
&.B__E--M {
// Color i want
}
}
}
You are looking for the double ampersand selector.
.B {
&__E {
color:black;
&#{&}--M{
color:white;
}
}
}
/* // Outputs:
.B__E {
color: black;
}
.B__E.B__E--M {
color: white;
}
*/

Using LESS variables in HTML Data Attribute in "quotes"

I am currently converting code from SASS to LESS.
I have a problem with the following line of code:
&[data-rating = "#{counter - 0.5}"] { // THIS DOES NOT WORK
How can I work with variables and subtract 0.5 from my counter var and have it in a pair of quotes so that it can sit inside the HTML data attribute.
I have included two code examples so you can take the code and run it to see my results.
SASS:
.reviews-stars {
display: inline-block;
#for $i from 1 through 5 {
&[data-rating = "#{$i}"] {
.star:nth-child(-n + #{$i}):before {
color: green;
}
}
&[data-rating = "#{$i - 0.5}"] {
.star:nth-child(-n + #{$i}):before {
color: red;
}
}
}
}
LESS:
.looper-review-stars(#counter) when (#counter > 0) {
.looper-review-stars((#counter - 1)); // next iteration
&[data-rating = "#{counter}"] { // THIS WORKS
.star:nth-child(-n + #{counter}):before { // THIS WORKS
color: green;
}
}
// THIS DOES NOT WORK IT RETURNS THE STRING "#{counter - 0.5}"
&[data-rating = "#{counter - 0.5}"] { // THIS DOES NOT WORK
.star:nth-child(-n + #{counter}):before { // THIS WORKS
color: red;
}
}
}
.reviews-stars {
display: inline-block;
.looper-review-stars(5); // launch the loop
}
You can do it using a temporary variable like in the below snippet. Since selectors are strings I think it is better to keep all math operations away from it and in a separate statement.
.looper-review-stars(#counter) when (#counter > 0) {
.looper-review-stars((#counter - 1)); // next iteration
&[data-rating = "#{counter}"] {
.star:nth-child(-n + #{counter}):before {
color: green;
}
}
#temp: #counter - .5; /* temporary variable */
&[data-rating = "#{temp}"] {
.star:nth-child(-n + #{counter}):before {
color: red;
}
}
}
.reviews-stars {
display: inline-block;
.looper-review-stars(5); // launch the loop
}

Alternate between two different colors every 3 elements with only 1 selector

I have a list of tr elements and I want to add CSS on them with the following pattern :
red
red
red
black
black
black
red
red
red
black
etc.
How can I do this ? for now I've been using :
tr:nth-child(6n+1) { color: red; }
tr:nth-child(6n+2) { color: red; }
tr:nth-child(6n+3) { color: red; }
... but how can I do it with only 1 selector ?
EDIT : Here is a jsfiddle link https://jsfiddle.net/1s5s05vk/2/
I think it will work faster with using css.
.mytable tr:nth-child(6n+1), .mytable tr:nth-child(6n+2), .mytable tr:nth-child(6n+3) {
background-color: red;
}
But if you want, you could use javascript for this.
As I said before.. you could add a class like "red" to any element that has iterator%6 (iterator mod 6) lower than 4.
var rows = document.getElementsByTagName('tr');
for (var i = 0, len = rows.length; i < len; i++){
if(i%6 < 4) {
rows[i].classList.add("red");
}
}
try this. Maybe it can help you.
tr:nth-child(-n+3) {
background: red;
}
tr:nth-child(n+4) {
background: blue;
}
What you want to do cannot be done with a single selector using CSS alone.
However, you can shorten the definition so you don't repeat code:
tr:nth-child(6n+1),
tr:nth-child(6n+2),
tr:nth-child(6n+3) {
color: red;
}

how to pass a string to a mixin and generate a dynamic variable to output color in LESSCSS?

//call the mixin
.mixin-loop(grey, 7);
//the implementation
.mixin-loop(#str, #count) {
.loop (#i) when (#i > 0) {
.#{str}-#{i} {
div { background: "#{#{str}-#{i}}"; }
}
.loop(#i - 1);
}
.loop (#count);
}
//globals.less
#grey-1: #ccc;
#grey-2: #999;
The output I want is this:
//output
.grey-1 div {
background: #ccc;
}
.grey-2 div {
background: #999;
}
But what I'm getting is this:
.#808080-1 div {
background: "#{#808080-1}";
}
.#808080-2 div {
background: "#{#808080-2}";
}
You can use variable interpolation (~) to help with this:
http://lesscss.org/features/#variables-feature-variable-interpolation
This will prevent grey from being converted into it's hex value, and then will allow "#{#{str}-#{i}}" to be displayed as a hex value instead of a string.
//call the mixin
.mixin-loop(~"grey", 2);
//the implementation
.mixin-loop(#str, #count) {
.loop (#i) when (#i > 0) {
.#{str}-#{i} {
div { background: ~"#{#{str}-#{i}}"; }
}
.loop(#i - 1);
}
.loop (#count);
}
//globals.less
#grey-1: #ccc;
#grey-2: #999;

How to change a class format based on body's class with SCSS?

I am making a web app that is used in three (or more) different contexts, and I want each context to have a different color scheme. However, I don't want to have to maintain three different stylesheets when all that changes is colors, typically.
For instance, suppose the themes are red, blue, and orange. One of my stylesheets describes the link colors:
a {
color: $some_color;
}
I want to split this based on the class applied to the body:
body.style1 {
a {
color: $red;
}
}
body.style2 {
a {
color: $blue;
}
}
body.style3 {
a {
color: $orange;
}
}
You can see how this gets unwieldy pretty quickly if you're changing the style for lots of elements. Is there a way to do this more like this?
a {
&closest:body.style1 {
color: $red
}
&closest:body.style2 {
color: $blue;
}
&closest:body.style3 {
color: $orange;
}
}
This way I can code my scss in a clearer, more maintainable way.
It appers you don't have to have the & first, so this works (at least in 3.2.10):
a {
body.style1 & {
color: $red
}
body.style2 & {
color: $blue;
}
body.style3 &{
color: $orange;
}
}
This is what I prefer. Define a mixin like body-style :
#mixin body-style($style, $map) {
body.#{$style} & {
#each $property, $value in $map {
#{$property}: $value;
}
}
}
Then use this for every tag by passing $style as style class of body and $map as map of css keys and values.
a {
#include body-style(style1, (
color: red,
background: white
)
);
}
It will return :
body.style1 a {
color: red;
background: white;
}

Resources