How can I zerofill the index of a Sass for loop?

1k views Asked by At
@for $i from 1 through $layer-count {
    #layer-#{$i} { background: url('../layers/layer-#{$i}.png'); }
    // background images are named layer-0001.png and up
}

There must be a way to achieve this, but I haven't been able to find anything.

1

There are 1 answers

4
Martin Turjak On

You could do something like this:

@function zerofill($i) { @return #{str-slice("0000",0,4 - str-length(#{$i}))}$i; }

@for $i from 1 through $layer-count {
    $i: zerofill($i); // now $i holds the zro-filled value for further use
    #layer-#{$i} { background: url('../layers/layer-#{$i}.png'); }
}

DEMO


Or the same with a more general function, that takes a length for the zero-filled value:

@function rep($n, $s: "0") {
    $out: $s;
    @while str-length($out) < $n { $out: $out + $s; }
    @return $out;
}
@function zerofill($i, $n) { @return #{rep($n - str-length(#{$i}))}$i; }

DEMO


Note:

To be able to use the string functions you need to run Sass v3.3, so I quickly rewrote the general function so that it works in older Sass versions (I threw in pow() too that is also already integrated in v3.3, so then you could just use the zerofill() part of this):

@function pow($b, $n) {
  $f: $b; @while $n > 1 { $f: $f * $b; $n: $n - 1; } @return $f;
}
@function zerofill($i, $n){
  $f: pow(10, $n - 1); $out: null;
  @while $f >= 1 {
    $out: $out#{floor($i / $f)}; $i: $i - floor($i / $f) * $f; $f: $f / 10;
  } @return $out;
}

DEMO