artemartemov artemartemov - 3 months ago 21
Sass (Sass) Question

SCSS :nth-child mixin with array

So I was hoping someone could help me out with something that seemed simple.

I have a grid template set up with ads coming in, in various locations. Causing the structure of the code to be a bit complicated. Basically right now for me to get it looking just right, I am using quite a bit of &:nth-child selectors to remove / ad margins at various breakpoints.

Instead of me writing out things such as:

&:nth-child( 3 ),
&:nth-child( 10 ),
&:nth-child( 13 ),
&:nth-child( 17 ),
&:nth-child( 20 ),
&:nth-child( 23 ),
&:nth-child( 26 ),
&:nth-child( 30 ),
&:nth-child( 33 ),
&:nth-child( 37 ),
&:nth-child( 43 ) {
margin-right: $gutter-width;
}


I have been trying to create a mixing that would allow me to pass an array of integers and for the css to spit out what I showed above by calling something along the lines of

@include nth-children( 3, 10, 13, 17, 20...) {
margin-right: $gutter-width;
}


The only issue is that I also would need to be able to pass an equation as part of that list ( 20n - 5 ) or whatever the case may be.

I have tried a few things but can't seem to even get it close

@mixin nth-children($nths) {

@for $i from 1 through length($nths) {
&:nth-child(#{$i}) {
@content;
}
}


}

I want to prevent of creating a list first since the values will be ever changing on multiple different screen sizes and page layouts.

Thanks in advanced!

Answer

This works:

$gutter-width: 12px;
$array: ("2n+1", "1", "2");
div {
    @each $i in $array {
        &:nth-child( #{$i} ) {
            margin-right: $gutter-width;
        }
    }
}

To keep it in single line:

@function nth-child-adder($item) {
    @return "&:nth-child(" + $item + ")";
}

@function nth-child-namer($array) {
  $x: "";
  @each $i in $array {
    @if $x != "" {
        $x: append($x, "," + nth-child-adder($i));
    }
    @else{
        $x: append($x, nth-child-adder($i));
    }
  }
  @return $x;
}

$gutter-width: 12px;
$array: ("2n+1", "1", "2");
div {
    #{nth-child-namer($array)} {
        margin-right: $gutter-width;
    }
}