I'm trying to achieve the following code with a scss for loop:
.box {
margin-left: 0;
margin-right: 2%;
}
.box + .box {
margin-left: 2%;
margin-right: 0;
}
.box + .box + .box {
margin-left: 0;
margin-right: 2%;
}
...
My for loop in scss looks like this:
.box {
margin-left: 0;
margin-right: 2%;
#for $i from 1 through 4 {
$sel: if($i == 1, &, selector-nest($sel, &)) !global;
#{$sel} {
#if ($i % 2 == 0) {
margin-left: 0;
margin-right: 2%;
} #else {
margin-left: 2%;
margin-right: 0;
}
}
}
}
The result is this:
.box {
margin-left: 0;
margin-right: 2%;
}
.box .box {
margin-left: 2%;
margin-right: 0;
}
.box .box .box {
margin-left: 0;
margin-right: 2%;
}
...
But I don't know how i can add the adjacent sibling selector between the classes. Maybe I'm doing it the wrong way. Is there a better way to do it, or could i use a recursive function or something like that? :)
Thanks for your help
Is this what you want:
.box {
margin-left: 0;
margin-right: 2%;
#for $i from 1 through 4 {
$sel: if($i == 1, &, selector-nest(#{$sel} #{'+'}, &)) !global;
+ #{$sel} {
#if ($i % 2 == 0) {
margin-left: 0;
margin-right: 2%;
} #else {
margin-left: 2%;
margin-right: 0;
}
}
}
}
Related
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.
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).
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;
}
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);
I'm writing a mixin for adding a graphical effect to the corner of a box:
The mixin will accept a corner position (tl, tr, bl, br), size, and colors:
#mixin notch($notch-location, $size, $foreground-color, $background-color) {
%top--left {
#extend %notch;
&:before {
top: 0; left: 0;
border-width: $size $size 0 0;
}
}
// etc ...
%notch {
position: relative;
&:before {
#extend .pel;
position: absolute;
border-style: solid;
border-color: $foreground-color $background-color;
}
}
#if $notch-location == top-left {
#extend %top--left;
}
// etc ...
}
I then use the mixin on a selector, for example:
a {
#include notch(top-left, 24px, $color-brand, #fff);
}
Unfortunately the resulting CSS isn't what I'm expecting:
.menu.collapsed .nav .nav--current a a:before {
top: 0;
left: 0;
border-width: 24px 24px 0 0;
}
.menu.collapsed .nav .nav--current a a {
position: relative;
}
.menu.collapsed .nav .nav--current a a:before {
position: absolute;
border-style: solid;
border-color: #ec5b25 white;
}
Example:
SCSS (jsFiddle)
Compiled CSS (jsFiddle)
As you can see, the styles added via the mixin are being qualified with an extra a. Why is this happening?
The output is exactly as I would expect because of the nature of extends. The %notch class belongs to the parent selector (a in your case). If you change it to .notch instead, it becomes obvious.
Extend classes are not ephemeral. It's a good idea to avoid defining them within a mixin you plan on reusing. Doing so will cause the class to be generated each time you invoke the mixin, causing duplication of code all over the place (which you probably don't want).
%notch {
position: relative;
&:before {
#extend .pel;
position: absolute;
border-style: solid;
}
}
#mixin notch($notch-location, $size, $foreground-color, $background-color) {
#extend %notch;
border-color: $foreground-color $background-color;
&:before {
#if $notch-location == top-left {
top: 0; left: 0;
border-width: $size $size 0 0;
} #else if $notch-location == top-right {
top: 0; right: 0;
border-width: $size 0 0 $size;
} #else if $notch-location == bottom-left {
bottom: 0; left: 0;
border-width: 0 $size $size 0;
} #else {
bottom: 0; right: 0;
border-width: 0 0 $size $size;
}
}
}
a {
display: block;
width: 100px; height: 100px;
background: #0f0;
#include notch(top-left, 24px, #0f0, #0f0);
}
It's also worth noting that extends aren't always the best choice, they can cause the code to be larger than it would be if you'd simply duplicated the code due to repeating the selector.
You seem to have messed up your code structure.
I'm not sure why this extra a appears, but when i refactor your code to have reasonable structure, the problem disappears:
$color-brand: pink;
%notch {
position: relative;
&:before {
#extend .pel !optional;
position: absolute;
border-style: solid;
}
}
%top--left {
#extend %notch;
&:before {
top: 0; left: 0;
}
}
#mixin notch($notch-location, $size, $foreground-color, $background-color) {
border-color: $foreground-color $background-color;
#if $notch-location == top-left {
#extend %top--left;
border-width: $size $size 0 0;
}
// etc ...
}
a {
#include notch(top-left, 24px, $color-brand, #fff);
}
Demo: http://sassbin.com/gist/6019481/