Incrementing Variable in Loop - visual-studio

I've got the following loop producing some styles for a tag cloud. On the online generators it produces the I'd consider the correct css styles, however in the visual studio solution (2012) which auto produces the css it seems to hang up. (see below) the less. Is there a more proper way to produce something like this via less that won't confuse the VS .less generator?
#iterations: 10;
#maxSize: 40;
#minSize: 10;
.tag-loop (#i) when (#i > -1) {
#j: (#i*(30/#iterations) + #minSize);
li.tag-#{i} {
font-size:~"#{j}px";
}
.tag-loop(#i - 1);
}
.tag-loop (#iterations);
Produces via visual studio:
ul.tag-cloud li.tag-10 {
font-size: 10px;
}
ul.tag-cloud li.tag-9 {
font-size: 10px;
}
ul.tag-cloud li.tag-8 {
font-size: 10px;
}
ul.tag-cloud li.tag-7 {
font-size: 10px;
}
ul.tag-cloud li.tag-6 {
font-size: 10px;
}
ul.tag-cloud li.tag-5 {
font-size: 10px;
}
ul.tag-cloud li.tag-4 {
font-size: 10px;
}
ul.tag-cloud li.tag-3 {
font-size: 10px;
}
ul.tag-cloud li.tag-2 {
font-size: 10px;
}
ul.tag-cloud li.tag-1 {
font-size: 10px;
}
ul.tag-cloud li.tag-0 {
font-size: 10px;
}
If I use something like http://winless.org/online-less-compiler the following is more accurately produced:
li.tag-10 {
font-size: 40px;
}
li.tag-9 {
font-size: 37px;
}
li.tag-8 {
font-size: 34px;
}
li.tag-7 {
font-size: 31px;
}
li.tag-6 {
font-size: 28px;
}
li.tag-5 {
font-size: 25px;
}
li.tag-4 {
font-size: 22px;
}
li.tag-3 {
font-size: 19px;
}
li.tag-2 {
font-size: 16px;
}
li.tag-1 {
font-size: 13px;
}
li.tag-0 {
font-size: 10px;
}

It looks like your VS uses (via Web Essentials 2012?) quite outdated Less 1.3.3 which handles variable scope quite differently, i.e. #j defined in the last iteration overrides all previous #j definitions.
The workaround to this is to calculate font-size value directly:
#iterations: 10;
#maxSize: 40;
#minSize: 10;
.tag-loop (#i) when (#i > -1) {
li.tag-#{i} {
font-size: unit((#i * (30 / #iterations) + #minSize), px);
}
.tag-loop((#i - 1));
}
.tag-loop (#iterations);

Related

CSS margin loop incrementing by X amount each time

I wonder if it is possible to do this with SCSS? Incrementing by X each time.
It is tricky because the -s or -md needs to be updated instead of the number.
#for $i from 1 through 6 {
.u-marg-t-#{$i} {
margin-top: 0px + ($i * 8);
}
}
Aside from this not even counting correctly, is a #for the best approach, here?
Plain CSS output
.u-marg-t {
&-xs {
margin-top: 8px;
}
&-sm {
margin-top: 16px;
}
&-md {
margin-top: 24px;
}
&-lg {
margin-top: 32px;
}
&-xl {
margin-top: 43px;
}
&-xxl {
margin-top: 50px;
}
}
.u-marg-b {
&-xs {
margin-bottom: 8px;
}
&-sm {
margin-bottom: 16px;
}
&-md {
margin-bottom: 24px;
}
&-lg {
margin-bottom: 32px;
}
&-xl {
margin-bottom: 43px;
}
&-xxl {
margin-bottom: 50px;
}
}
You could use a list with the suffixes you want to use and iterate through inside your for loop. Here's an example:
$sizes: xs, sm, md, lg, xl, xxl;
#for $i from 1 through 6 {
.u-marg-t-{
&#{nth($sizes, $i)} {
margin-top: 0px + ($i * 8);
}
}
}
$sizes is your list with the suffixes. Inside the loop I used the function nth($list, $i) to get the item at position $i in your list.

Sass (SCSS) - How to Add to Individual Values in a Class

I want to add 2px to the padding all around an element. So
padding: 10px 14px;
will become
padding: 14px 18px;. How can I achieve this?
Hopefully there is a more elegant solution than (psuedo-code):
$horizontal-padding: 10;
$vertical-padding: 14;
.normal-padding {
padding-top: $vertical-padding;
padding-right: $horizontal-padding;
padding-bottom: $vertical-padding;
padding-left: $horizontal-padding;
}
.extra-padding {
($horizontal-padding + 2 + px), ($vertical-padding + 2 + px);
}
Surely there must be a better way?
Actually, you can write that in a lot of ways. A solution similar to your code could be:
$vertical-padding: 14px;
$horizontal-padding: 10px;
.normal-padding {
padding: $vertical-padding $horizontal-padding;
}
.normal-padding {
$extra: 2px;
padding: #{$vertical-padding + $extra} #{$horizontal-padding + $extra};
}
A more dynamical way (not really useful if you only have these two variations though):
#mixin padding($extra : 0) {
padding: #{14 + $extra}px #{10 + $extra}px;
}
.normal-padding {
#include padding;
}
.extra-padding {
#include padding(2);
}
You can even change the code above to keep the $vertical-padding and $horizontal-padding variables. As I said, there are many ways to do it.
Just for fun. You can use css custom properties:
div {
border: 1px solid;
}
:root {
/* declare global variables */
--padding-x: 10px;
--padding-y: 10px;
}
.padded {
padding: var(--padding-y) var(--padding-x);
}
.extra {
/* redefine variables for `extra` elements */
--padding-x: 30px;
--padding-y: 30px;
}
<div class="padded"></div>
<div class="padded extra"></div>

DRY Sass codes that only value changes

Using sass with rails. In the design, there is a pattern that the space shrink to half from desktop to mobile. Now it ends up like:
.my-page {
.class-a {
margin-top: 20px;
margin-bottom: 20px;
}
.class-b {
padding-top: 30px;
padding-bottom: 30px;
}
}
#media(min-width: 768px) {
.my-page {
.class-a {
margin-top: 40px;
margin-bottom: 40px;
}
.class-b {
padding-top: 60px;
padding-bottom: 60px;
}
}
}
Wondering is there a good way to DRY these? Don't wanna repeat writing same classes twice.
A nice way to DRY up your sass is using mixins.
#mixin page-spaces($margin, $padding) {
.my-page {
.class-a {
margin-top: $margin;
margin-bottom: $margin;
}
.class-b {
padding-top: $padding;
padding-bottom: $padding;
}
}
}
#include page-spaces(20px, 30px);
#media(min-width: 768px) {
#include page-spaces(40px, 60px);
}
SASS Reference on Mixins
Edit: In order to clarify the intended use of mixins, here's an extended version with multiple arguments (even a default):
#mixin awesome-page-stuff($stylish-margin, $cute-padding, $some-left-margin, $ugly-background: red) {
.my-page {
background: $ugly-background;
.class-a {
margin-top: $stylish-margin;
margin-bottom: $stylish-margin;
}
.class-b {
padding-top: $cute-padding;
padding-bottom: $cute-padding;
margin-left: $some-left-margin;
}
}
}
#include awesome-page-stuff(20px, 30px, 50px);
#media(min-width: 768px) {
#include awesome-page-stuff(40px, 60px, 200px, green);
}
you can create variables, something like this:
$primary-margin: 20px;
$primary-padding: 30px;
.my-page {
.class-a {
margin-top: $primary-margin;
margin-bottom: $primary-margin;
}
.class-b {
padding-top: $primary-padding;
padding-bottom: $primary-padding;
}
}
#media(min-width: 768px) {
.my-page {
.class-a {
margin-top: $primary-margin*2;
margin-bottom: $primary-margin*2;
}
.class-b {
padding-top: $primary-padding*2;
padding-bottom: $primary-padding*2;
}
}
}

Not able to find pre-defined sass variables in Jekyll project

I'm new the Jeykll and Sass and have a quick question. Within the pre-built theme when starting a new project, where are these variables defined?
I can't seem to find them aware through out the build.
This is in the _sass/layout.scss directory.
*/
.site-header {
border-top: 5px solid $grey-color-dark;
border-bottom: 1px solid $grey-color-light;
min-height: 56px;
// Positioning context for the mobile navigation icon
position: relative;
}
.site-title {
font-size: 26px;
line-height: 56px;
letter-spacing: -1px;
margin-bottom: 0;
float: left;
&,
&:visited {
color: $grey-color-dark;
}
}
.site-nav {
float: right;
line-height: 56px;
.menu-icon {
display: none;
}
.page-link {
color: $text-color;
line-height: $base-line-height;
// Gaps between nav items, but not on the first one
&:not(:first-child) {
margin-left: 20px;
}
}
#include media-query($on-palm) {
position: absolute;
top: 9px;
right: 30px;
background-color: $background-color;
border: 1px solid $grey-color-light;
border-radius: 5px;
text-align: right;
.menu-icon {
display: block;
float: right;
width: 36px;
height: 26px;
line-height: 0;
padding-top: 10px;
text-align: center;
> svg {
width: 18px;
height: 15px;
path {
fill: $grey-color-dark;
}
}
}
.trigger {
clear: both;
display: none;
}
&:hover .trigger {
display: block;
padding-bottom: 5px;
}
.page-link {
display: block;
padding: 5px 10px;
}
}
}
/**
* Site footer
*/
.site-footer {
border-top: 1px solid $grey-color-light;
padding: $spacing-unit 0;
}
.footer-heading {
font-size: 18px;
margin-bottom: $spacing-unit / 2;
}
.contact-list,
.social-media-list {
list-style: none;
margin-left: 0;
}
.footer-col-wrapper {
font-size: 15px;
color: $grey-color;
margin-left: -$spacing-unit / 2;
#extend %clearfix;
}
.footer-col {
float: left;
margin-bottom: $spacing-unit / 2;
padding-left: $spacing-unit / 2;
}
.footer-col-1 {
width: -webkit-calc(35% - (#{$spacing-unit} / 2));
width: calc(35% - (#{$spacing-unit} / 2));
}
.footer-col-2 {
width: -webkit-calc(20% - (#{$spacing-unit} / 2));
width: calc(20% - (#{$spacing-unit} / 2));
}
.footer-col-3 {
width: -webkit-calc(45% - (#{$spacing-unit} / 2));
width: calc(45% - (#{$spacing-unit} / 2));
}
#include media-query($on-laptop) {
.footer-col-1,
.footer-col-2 {
width: -webkit-calc(50% - (#{$spacing-unit} / 2));
width: calc(50% - (#{$spacing-unit} / 2));
}
.footer-col-3 {
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
width: calc(100% - (#{$spacing-unit} / 2));
}
}
#include media-query($on-palm) {
.footer-col {
float: none;
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
width: calc(100% - (#{$spacing-unit} / 2));
}
}
/**
* Page content
*/
.page-content {
padding: $spacing-unit 0;
}
.page-heading {
font-size: 20px;
}
.post-list {
margin-left: 0;
list-style: none;
> li {
margin-bottom: $spacing-unit;
}
}
.post-meta {
font-size: $small-font-size;
color: $grey-color;
}
.post-link {
display: block;
font-size: 24px;
}
/**
* Posts
*/
.post-header {
margin-bottom: $spacing-unit;
}
.post-title {
font-size: 42px;
letter-spacing: -1px;
line-height: 1;
#include media-query($on-laptop) {
font-size: 36px;
}
}
.post-content {
margin-bottom: $spacing-unit;
h2 {
font-size: 32px;
#include media-query($on-laptop) {
font-size: 28px;
}
}
h3 {
font-size: 26px;
#include media-query($on-laptop) {
font-size: 22px;
}
}
h4 {
font-size: 20px;
#include media-query($on-laptop) {
font-size: 18px;
}
}
}
Notice: Jekyll has since been updated, its default theme, minima, is now in a separate gem, and the definitions are there, in _sass/minima.scss.
Look at this, with relative path to site root in default Jekyl site css/main.scss. There they are. After all the definitions, imports and processing, there will be css/main.css in the resulting site.
Everything in _sass is just for importing into real assets that will be converted to CSS. The difference between Sass/SCSS files in _sass and everywhere else is that files from _sass are not compiled directly, but rather just lay where they are and wait to be imported. Every possibly reusable piece of Sass should be in _sass, that's what Sass partials and this system overall is designed for. This is especially useful if you use a lot of Sass libraries (like I do, and it's still a mess) and don't want them to be modified in order to be put into your assets.
All the other files (not in _sass), however, will be processed into corresponding *.css files, and in order to distinguish files for processing, Jekyll requires such files to have a YAML front-matter, usually empty.
---
---
// Sass code here
(I used to utilize Liquid for embedding variables in Sass, but that feature vanished after some updates, so now non-empty YFM in assets is of no use now).

SCSS repeat value?

I'm trying to work out on SCSS how I would go about something like this:
I would like to have a margin anywhere between 1px and 1000px and have a class for it.
For example
.MarginTop-x
X being where I can write any value. Obviously I couldn't write out
.MarginTop-1 {margin-top:1px}
.MarginTop-2 {margin-top:2px}
.MarginTop-3 {margin-top:3px}
.MarginTop-4 {margin-top:4px}
etc...
Well you need a #for loop to do that .
SCSS :
$class-slug: ".MarginTop";
$stop-loop: 4;
#for $i from 0 through $stop-loop {
#{$class-slug}-#{$i} {
margin-top: #{$i}px;
}
}
Compiled CSS:
.MarginTop-0 {
margin-top: 0px; }
.MarginTop-1 {
margin-top: 1px; }
.MarginTop-2 {
margin-top: 2px; }
.MarginTop-3 {
margin-top: 3px; }
.MarginTop-4 {
margin-top: 4px; }
Not sure of the utility of this, but...
Sass:
#mixin marginTop($amount) {
.marginTop-#{$amount} {
margin-top: unquote($amount + 'px');
}
}
#include marginTop(1);
#include marginTop(100);
Compiled CSS:
.marginTop-1 {
margin-top: 1px;
}
.marginTop-100 {
margin-top: 100px;
}

Resources