Sass increment class in variable - css

Helo i just learning sass and trying to make dynamic class by looping. and my code just like this
$col-width-1: 1/12*100%;
$col-width-2: 2/12*100%;
$col-width-3: 3/12*100%;
$col-width-4: 4/12*100%;
$col-width-5: 5/12*100%;
$col-width-6: 6/12*100%;
$col-width-7: 7/12*100%;
$col-width-8: 8/12*100%;
$col-width-9: 9/12*100%;
$col-width-10: 10/12*100%;
$col-width-11: 11/12*100%;
$col-width-12: 12/12*100%;
.col-1{
width: $col-width-1;
}
.col-2{
width: $col-width-2;
}
.col-3{
width: $col-width-3;
}
.col-4{
width: $col-width-4;
}
.col-5{
width: $col-width-5;
}
.col-6{
width: $col-width-6;
}
.col-7{
width: $col-width-7;
}
.col-8{
width: $col-width-8;
}
.col-9{
width: $col-width-9;
}
.col-10{
width: $col-width-10;
}
.col-11{
width: $col-width-11;
}
.col-12{
width: $col-width-12;
}
$columns: 12;
$padding-mini: 10px;
#for $i from 1 through $columns {
.col-#{$i} {
width: calc(#{$col-width-#{$i}} - #{$padding-mini});
}
}
is possible to make dynamic or increment variable inside the loop ?
when i check the console. the error caused by this code:
width: calc(#{$col-width-#{$i}} - #{$padding-mini});
i have search on internet but i can't get any clear solutions. thanks for your answer

You can't reference variables dynamically with SASS. However, since all your variables use the same calculation you can simply put it directly in the loop:
$columns: 12;
$padding-mini: 10px;
#for $i from 1 through $columns {
.col-#{$i} {
width: calc(#{$i}/#{$columns}*100% - #{$padding-mini});
}
}
You can also write it like this:
width: calc(#{$i/$columns}*100% - #{$padding-mini});

Related

How can I use a loop in LESS to create specific class names for typography?

I want to generate 9 typography classes, each with the following:
font-size: 2rem;
line-height: 1rem;
I'll be using standard typographic multipliers for font sizes and line-height. Instead of hard-coding all of these CSS classes, I was wondering if there was a more elegant way of generating them in a loop using LESS.
I found the following from another thread:
#iterations: 5;
.span-loop (#i) when (#i > 0) {
.span-#{i} {
width: ~"#{i}%";
}
.span-loop(#i - 1);
}
.span-loop (#iterations);
Which generates:
.span-5 {
width: 5%;
}
.span-4 {
width: 4%;
}
.span-3 {
width: 3%;
}
.span-2 {
width: 2%;
}
.span-1 {
width: 1%;
}
This is pretty close, but I'd love for my class names to more "named". How can I use a loop to generate classes for:
.small { }
.caption { }
.body { }
.subheader { }
.title { }
.headline { }
etc...
I'm also not tied to LESS, so if there's a better CSS preprocessor language, then I'm happy to use that instead :)
Thank you!
An example from documentation for further modification;)
for more complicated code, it is better to use scss than less
.for(#list, #code) {
& {
.loop(#i: 1) when (#i =< length(#list)) {
#value: extract(#list, #i);
#code();
.loop(#i + 1);
}
.loop();
}
}
#elements: small, caption, body, subheader, title, headline;
.for(#elements, {
#remfont: #i+1;
#remline: ((#i+1) * 1.5 / 3);
.#{value} {
font-size: ~"#{remfont}rem";
line-height: ~"#{remline}rem";
}
});

Using SASS's #for for multiple selectors and 1 body [duplicate]

I'm working with the SCSS syntax of SASS to create a dynamic grid system but I've hit a snag.
I'm trying to make the grid system completely dynamic like this:
$columns: 12;
then I create the columns like this:
#mixin col-x {
#for $i from 1 through $columns {
.col-#{$i} { width: $column-size * $i; }
}
}
Which outputs:
.col-1 {
width: 4.16667%;
}
.col-2 {
width: 8.33333%;
}
etc...
This works well but what I want to do next is dynamically generate a long list of column classes separated by commas based on the number of $columns chosen - e.g I want it to look like this:
.col-1,
.col-2,
.col-3,
.col-4,
etc... {
float: left;
}
I've tired this:
#mixin col-x-list {
#for $i from 1 through $columns - 1 {
.col-#{$i}-m { float: left; }
}
}
but the output is this:
.col-1 {
float: left;
}
.col-2 {
float: left;
}
etc...
I'm a little stuck on the logic here as well as the SCSS syntax required to create something like this.
Does anyone have any ideas?
I think you may want to take a look at #extend. If you set that up something like:
$columns: 12;
%float-styles {
float: left;
}
#mixin col-x-list {
#for $i from 1 through $columns {
.col-#{$i}-m { #extend %float-styles; }
}
}
#include col-x-list;
It should render in your css file as:
.col-1-m, .col-2-m, .col-3-m, .col-4-m, .col-5-m, .col-6-m, .col-7-m, .col-8-m, .col-9-m, .col-10-m, .col-11-m, .col-12-m {
float: left;
}
#extend in the docs.
There's also a way to do what your question is specifically asking for: generate (and use) a list of classes with commas separating them. D.Alexander's response totally works in your situation, but I'm posting this alternative in case there's another use case for someone looking at this question.
Here's a Pen demonstrating: http://codepen.io/davidtheclark/pen/cvrxq
Basically, you can use Sass functions to achieve what you want. Specifically, I'm using append to add classes to my list, separated by commas, and unquote to avoid compilation conflicts with the period in the classnames.
So my mixin ends up looking like this:
#mixin col-x {
$col-list: null;
#for $i from 1 through $columns {
.col-#{$i} {
width: $column-size * $i;
}
$col-list: append($col-list, unquote(".col-#{$i}"), comma);
}
#{$col-list} {
float: left;
}
}
thnx to #davidtheclark here is a more generic version:
#mixin attr-x($attr, $attr-count: 10, $attr-steps: 10, $unit: '%') {
$attr-list: null;
#for $i from 1 through $attr-count {
$attr-value: $attr-steps * $i;
.#{$attr}#{$attr-value} {
#{$attr}: #{$attr-value}#{$unit};
}
$attr-list: append($attr-list, unquote(".#{$attr}-#{$attr-value}"), comma);
}
#{$attr-list} {
//append style to all classes
}
}
Use it like this:
#include attr-x('margin-left', 6, 5, 'px');
//or
#include attr-x('width');
The result looks like this:
.margin-left5 {
margin-left: 5px; }
.margin-left10 {
margin-left: 10px; }
...
.margin-left30 {
margin-left: 30px; }
.width10 {
width: 10%; }
.width20 {
width: 20%; }
...
.width100 {
width: 100%; }

Does Sass has different operator (!=)?

In trying to make a mixin in Sass, here is the example
#mixin icon($w,$h,$float:'null') {
width: $w;
height: $h;
#if $float != 'null'{
float: $float;
}
}
But i get an error, I don't know if Sass supports that kind of comparison or i'm doing something wrong...
try this:
#mixin icon($w,$h,$float: null) {
width: $w;
height: $h;
#if $float != null {
float: $float;
}
}
or try the documentation http://sass-lang.com/documentation/file.SASS_REFERENCE.html#_9

Less CSS variable encapsulation and reusable mixins

Can anyone offer any solutions for combining encapsulation and mixin reuse for Less/CSS? I'm trying to keep my variables encapsulated by namespace, but I haven't figured out how to reuse mixins for it.
Example:
#signup-module {
#button-width: 100px;
#button-height: 30px;
#textfield-width: 300px;
#textfield-height: 20px;
.width( #value, #mod:0 ) {
width: ##value + #mod;
}
.height( #value, #mod:0 ) {
height: ##value + #mod;
}
}
.home-page-signup-module {
#signup-module > .width( button-width, -20px );
#signup-module > .height( button-height, -20px );
#signup-module > .width( textfield-width );
#signup-module > .height( textfield-height );
}
The problem is when I create a new module, the width() and height() mixins are repeated.
#contact-us-module {
#button-width: 50px;
#button-height: 20px;
#textfield-width: 300px;
#textfield-height: 20px;
.width( #value, #mod:0 ) {
width: ##value + #mod;
}
.height( #value, #mod:0 ) {
height: ##value + #mod;
}
}
Is there a way to maintain variable encapsulation and eliminate the mixin repetition? I'd like to write .width() and .height() once, but :extend() doesn't seem to work in this context.
Update: May 15, 2014
seven-phases-max offered a great solution below for reusing mixins, but I think I ran into a variable scope issue and the statement below returned an error. It said, "variable #textfield-width is undefined."
.home-page-signup-module {
.module-a.width(textfield-width, -20px);
}
So I tried adding .module-a which seems to work. I'm not 100% sure if this is correct usage but it does fix the error and return the correct value.
.home-page-signup-module {
.module-a;
.module-a.width(textfield-width, -20px);
}
You can collect shared mixins into another namespace/mixin and expand it in each "module" you need, something like this for example:
.shared-stuff() {
.width(#value, #mod: 0) {
width: ##value + #mod;
}
.height(#value, #mod: 0) {
height: ##value + #mod;
}
}
.module-a {
.shared-stuff();
#button-width: 100px;
#button-height: 30px;
#textfield-width: 300px;
#textfield-height: 20px;
}
.module-b {
.shared-stuff();
#button-width: 200px;
// etc.
}
// usage:
.home-page-signup-module {
.module-a.width(button-width, -20px);
.module-b.width(button-width, +33px);
}

Sass: Change color with #for loop

I try to darken a variable number of divs like that
with following code:
#mixin color-divs ($count, $baseName, $startcolor) {
$color: $startcolor;
#for $i from 0 through $count {
$color: darken($color, 9%);
##{$baseName}_#{$i} { background-color:$color; }
}
}
With that code I was expecting, that the variable $color is changed with every iteration but this didn't work as expected. The value is fix after the fist initialisation and every element has the same color.
Is there a way to workarround that problem or is there another way to solve that problem with a mixing?
You can darken the color using $i inside #for and apply respective classes to the divs. Hope this helps.
SCSS
#mixin color-divs ($count, $baseName, $startcolor) {
#for $i from 0 through $count {
$background-color: darken($startcolor, $i * $i);
.colored-div#{$i} {
background: $background-color;
height:100px;
width:200px;
float: left;
margin-right: 5px;
}
}
}
#include color-divs(5,'a',#ffd8b1);
HTML
<div class="colored-div1">a</div>
<div class="colored-div2">b</div>
<div class="colored-div3">c</div>
<div class="colored-div4">d</div>
<div class="colored-div5">e</div>
Demo
See demo
I created this example based on your mixin:
#mixin color-divs ($count, $baseName, $startcolor) {
$loop_color: $startcolor;
#for $i from 0 through $count {
$loop_color: darken($loop_color, 9%);
.#{$baseName}-#{$i} { background-color: $loop_color; }
}
}
div {
width: 100px;
height: 100px;
float: left;
}
#include color-divs(6,'div',#faa)
Used with the following markup:
<div class="div-1"></div>
<div class="div-2"></div>
<div class="div-3"></div>
<div class="div-4"></div>
<div class="div-5"></div>
<div class="div-6"></div>
Output: http://jsfiddle.net/jdtvF/
http://uk.omg.li/P0dF/by%20default%202013-05-16%20at%2010.10.43.png
div {
width: 100px;
height: 100px;
float: left; }
.div-0 {
background-color: #ff7c7c; }
.div-1 {
background-color: #ff4e4e; }
.div-2 {
background-color: #ff2020; }
.div-3 {
background-color: #f10000; }
.div-4 {
background-color: #c30000; }
.div-5 {
background-color: #960000; }
.div-6 {
background-color: #680000; }
To just go from one color to another, for say, a number of consecutive <div>:
#for $i from 0 through 11
&:nth-child(#{$i})
transform: rotate(#{30*$i}deg)
background-color: mix($gray1, $gray2, $i / 12 * 100% )
Notes
Note, that you don't need any #{…} inside the mix(), because it's a sass function, so it's clear that any variables and computations used insides are to be resolved before turning it into CSS.
The transform is just my use case (for demonstration). Here, one does need #{…}
and note the +/-1 issue (like in every for-loop, in any language): going from 0/12 to 11/12
lastly, turning it into a percentage to please the mix function
as you see: could be done in a mixin, but doesn't have to be!

Resources