Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 252
artemartemov Avatar asked Aug 10 '16 20:08

artemartemov


People also ask

How do I select nth child in SCSS?

You can pass in a positive number as an argument to :nth-child() , which will select the one element whose index inside its parent matches the argument of :nth-child() . For example, li:nth-child(3) will select the list item with an index value 3; that is, it will select the third list item.

How do you target the nth child in sass?

Writing Complex :nth-child() Selectors It works exactly the same as :nth-child except that it starts from the end of the parent. For example, you can select the first three children of a parent by using the selector :nth-child(-n + 3) . You can use :nth-last-child(-n + 3) to select the last three.

What is the nth child () selector used for?

Definition and Usage. The :nth-child(n) selector matches every element that is the nth child of its parent. n can be a number, a keyword (odd or even), or a formula (like an + b). Tip: Look at the :nth-of-type() selector to select the element that is the nth child, of the same type (tag name), of its parent.

Can we use Nth child for class?

The :nth-child selector allows you to select one or more elements based on their source order, according to a formula. It is defined in the CSS Selectors Level 3 spec as a “structural pseudo-class”, meaning it is used to style content based on its relationship with parent and sibling elements.


3 Answers

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;
    }
}
like image 54
Mr_Green Avatar answered Oct 21 '22 08:10

Mr_Green


the following mixin should work using @each:

@mixin nth-children($points...) {
  @each $point in $points {
    &:nth-child(#{$point}) {
      @content;
    }
  }
}

/* example call */
$gutter-width: 5px;
div {
  @include nth-children( 3, 10, 13, 17, 20, "2n + 1") {
      margin-right: $gutter-width;
  }
}
like image 37
simialbi Avatar answered Oct 21 '22 07:10

simialbi


you can use "list..." - depending on your precompiler version). I made a small codepen for it: http://codepen.io/anon/pen/AXYRNB

$params: (1, 2, 3, 4);

$paramsLength: length($params);

@function item($item) {
  @return nth($params, $item);
}

@mixin nth-children($params...) {
  @for $i from 1 through $paramsLength  {
    &:nth-child( #{item($i)} ) {
      margin-left: 2em; 
    }
  } 

}

ul {
  @include nth-children($params);
}

for more information, have a look a this: https://www.sitepoint.com/sass-multiple-arguments-lists-or-arglist/.

PS: this doesn't solve your issue with the "equation" - I don't really think that it's possible :-)

like image 38
Marouen Mhiri Avatar answered Oct 21 '22 09:10

Marouen Mhiri