Nesting Selectors via Loops with SASS

Produce nested selectors using SCSS loop?

Possible with a loop and selector-nest() depending on your use case.

$sel: '';
@for $i from 1 through 10 {
$sel: if($i == 1, "div", selector-nest($sel, "> div")) !global;

#{$sel} {
margin-top: 1px * $i;
}
}

Loop through nested SCSS list using key/value

As to your update in your question:

Here is a mixin example to your updated requirements.

The example is done in a more general way for multiple use and a good readability.

So font-sizing-settings works as well as margins or even (nearly) every other property setting you would like ot adapt to the breakpoints. And once more with map-element selector it works on simple elements (tags), on classes, id's and more complex selectors as well.

Additional to the $rules map it is based on a breakpoint map. That make sure it works on all breakpoints adviced to the project. But rules to the breakpoints are only added to an element if noted in the rule map ... so you can say: it's an universal swiss knife.

EXAMPLE:

//###### SASS
// this example assumes:
// breakpoints allways min-width ...
$breakpoints: (
sm: 768px,
md: 1024px,
lg: 1280px,
xl: 1400px
);

$rules: (

title: (

selector: 'h1',

all: (
font-family: 'Arial',
font-size: 26px,
line-height: 1.4,
),

sm: (
font-size: 26px,
line-height: 1.4,
),
lg: (
font-size: 80px,
line-height: 1.6,
),
xl: (
font-size: 100px,
),
),

text: (

selector: 'p',

all: (
font-family: 'Courier New',
font-size: 26px,
line-height: 1.4,
),

sm: (
font-size: 16px,
line-height: 1.2,
),
lg: (
font-size: 36px,
line-height: 1.4,
)
),

) !default;

@mixin fontSizing($rule-map, $breakpoints: $breakpoints){

@each $element, $settings-map in $rule-map {

$selector: map-get($settings-map, selector);

// write generel rules
#{$selector} {
@each $property, $value in map-get($settings-map, all){
#{$property}: $value;
}
}

// rules for every breakpoint
@each $breakpoint, $breakpoint-setting in $breakpoints {

// only if breakpoint values set for element
@if map-has-key( $settings-map, $breakpoint ){

// write breakpoints rule
@media ( min-width: #{$breakpoint-setting} ){
#{$selector} {
@each $property, $value in map-get($settings-map, $breakpoint){
#{$property}: $value;
}
}
}

}//if

}//each

}//each

}//mixin

//##### CALL MIXIN
@include fontSizing($rules);

//##### COMPILES TO...

h1 {
font-family: "Arial";
font-size: 26px;
line-height: 1.4;
}

@media (min-width: 768px) {
h1 {
font-size: 26px;
line-height: 1.4;
}
}
@media (min-width: 1280px) {
h1 {
font-size: 80px;
line-height: 1.6;
}
}
@media (min-width: 1400px) {
h1 {
font-size: 100px;
}
}
p {
font-family: "Courier New";
font-size: 26px;
line-height: 1.4;
}

@media (min-width: 768px) {
p {
font-size: 16px;
line-height: 1.2;
}
}
@media (min-width: 1280px) {
p {
font-size: 36px;
line-height: 1.4;
}
}


ADDITIONAL HINT/IMPULSE:

It is possible to compress the rule map. In that case the code working is less, - but more specialised to single tags only and the pre-defined font-sizing settings ... and it is less readable. The general construction of the mixin would be the same but code writing would change a little bit as you work with predefined properties and nested lists instead of nested maps. Feel free to adapt the code. Here is an example for the possible compression to the rule-map:

$rule: (
h1: (
fontFamily: 'Arial',
all: (10px, 1.2),
sm: (12px, 1.4),
lg: (24px, 1.6),
),
p: (
fontFamily: 'Courier New',
all: (8px, 1.2),
sm: (10px, 1.4),
lg: (20px, 1.6),
xl: (24px, 1.8),
),
) !default;

Grouping Selectors inside of a loop using Sass

Have you tried something like this:

@mixin createNumbered($num, $className){
@for $i from 1 through $num {
.#{$className}-#{$i} {
@content;
}
}
}

@include createNumbered(10, 'foo-bar'){
color: white;
}

Updated:

@mixin createNumbered($num, $className){
$foo : '';
@for $i from 1 through $num {
$foo : $foo + '.' + $className + '-' + $i + ', ';
}
#{$foo} {
@content;
}
}

@include createNumbered(10, 'foo-bar'){
color: white;
}

Programmatically nest rules with sass

The following SASS code should get you the result you are after. The @each statement will loop through each colour. The @for loop is based upon the index of the colour in the list and will append the correct number of .list to the selector.

$colors: green red blue orange;

@each $color in $colors {
$i: index($colors, $color);
@for $c from 1 through $i {
@if $c == 1 {
$selector: '.list';
} @else {
$selector: $selector '.list';
}
}
#{$selector} {
border-color: #{$color};
}
}

SASS Meister: http://sassmeister.com/gist/106687cca4d2a8ce5fc4

Using a list of selectors in combination with & in a nested selector in Sass SCSS

You could try something like this:

$classes: ".bodyClass1" , ".bodyClass2";

.aClass, .anotherClass {
/* some styles */
@for $i from 1 through 2 {
#{nth($classes, $i)} & {
/* Styles under $classes */
}

#{nth($classes, $i)} &:hover {
/* Styles under $classes when hovering */
}
}
}

An example: http://sassmeister.com/gist/acb0096e9d35e1ae437d

SASS: Append class selectors in loop

You can do it this way:

@for $i from 1 through 3 {
$class: '.menu';

@if $i > 1 {
@for $j from 1 through $i - 1 {
$class: $class + ' .submenu';
}
}
$class: $class + ' IMG';
#{$class} {
padding-left: #{$i * 10px};
}
}

SASS Looping Selector

You can use a for loop to generate the selector chain and then inject it into a rule with interpolation:

@mixin depth($depth: 1) {
$chain: '';
@for $i from 0 to $depth {
$chain: $chain + ' > ul > li';
}

& #{$chain} {
@content;
}
}

example | gist

SCSS @each nesting colours

Some parts of your code are a bit unclear so I will assume that what you are trying to do should be more like the following:

$days : (
saturday: blue,
sunday: green,
...
friday: red
);

@each $day, $color in $days {
.day-#{$day} {
background: rgba($color, 0.15);
& .weekday {
background: $color;
}
}
}

One notable mistake in your code is the bad syntax of your interpolations which should be write as #{$variable} and not ${$variable} or {variable}. Also, it is not required that you interpolate everything, you can look at the documentation to get a better understanding about this.

Then, since you need to associate days with colors you should use a map instead of a list. Using the @each loop let you access each values so you can use them where you need in the code.

Nested pseudo selectors with Sass

If you don't understand the rules of the selectors, where did you get the CSS from? Just curious.

a.) The rule is saying, for the 2nd and 3rd .modal-content, apply a left margin of 10px on the .feature-icon if one is there.

b.) When nested, those selectors will ONLY work in those instances. If you have another .feature-icon in say something with a class of .yellowBox, instead of .modal-content, it will not get the left margin. Nesting allows for quicker styling and gives your styles structure, but makes your selectors VERY specific the further in the nesting goes.

EDIT:
After further review, there will only be one .modal-content, you probably want this:

.modal-content {
.feature-bullet {
&:nth-child(2), &:nth-child(3){
.feature-icon{
margin-left: 10px;
}
}
}
}

The way you have your SASS right now, it says look for the 2nd and 3rd .modal-content, but there will only be one for the modal. Instead, you want to look for the 2nd and 3rd .feature-bullet, and apply the margin to the .feature-icon within those.



Related Topics



Leave a reply



Submit