Get a different random number within a SCSS for loop [duplicate] - for-loop

I need to output this:
#footer-widgets .container .row {
background-image: url("RANDOMLY PICKED");
background-position: right bottom;
background-repeat: no-repeat;
}
... and there should be a list with 4 or 5 links to the actual background-images (http://domain.com/blablabla/image.png) to pick from. How can I do this with SASS?

The most recent version of Sass (v3.3.0) adds a new random function. If you mix that with a list of images (and a wee bit of variable interpolation), you will have CSS with a randomly selected background image every time Sass is compiled. Example:
$imgKey: random(5);
$list: apple, banana, cherry, durian, eggplant;
$nth: nth($list, $imgKey);
body {
background-image: "/images/#{$nth}.jpg";
}
Live example: http://sassmeister.com/gist/8966210
As above, the random value will only change when the Sass is compiled, which won't necessarily be every time your page is visited.

Related

Conditional Sass Variables with Nativescript

Android and iOS render fonts in vastly different ways. I'd like to be able to get their renders looking a little more similar, so I need to change the font-sizes and weights throughout my entire app depending on whether it's on iOS or android.
Obviously, going through every place font-size or weight is defined and adding a conditional for is out of the question, and (fortunately) I already have all my font sizes and weights defined by sass variables.
Regardless of whether or not there is a better solution than conditional sass variables, I would like to know:
How can I conditionally select sass variables in nativescript?
I know that modules will use MyModule.ios.css or MyModule.android.css depending on the os. Can I take advantage of that?
Yes, you are on right track. You can have MyVariable.android.scss and MyVariable.ios.scss to define different values for Sass variable. In my code sharing project I have MyVariable.scss as well that I use for HTML(Web).
I have created a sample playground for you here.
In my home.component.ios.scss
$labelfontSize: 10;
$labelfontColor: red;
.home-panel{
vertical-align: center;
font-size: 20;
margin: 15;
}
.description-label{
margin-bottom: 15;
color: $labelfontColor;
font-size: $labelfontSize;
}
and in my home.component.android.scss
$labelfontSize: 18;
$labelfontColor: green;
.home-panel{
vertical-align: center;
font-size: 20;
margin: 15;
}
.description-label{
margin-bottom: 15;
color: $labelfontColor;
font-size: $labelfontSize;
}
It shows red text in ios while in android text is green.

sass mixin for linear-gradient, code explanation

I found the following mixin on the web, but have forgotten where I found it.
#mixin linear-gradient($direction, $gradients...) {
background-color: nth($gradients, 1);
background-image: linear-gradient($direction, $gradients...);
}
and then be called upon in a class with:
.selector {
#include linear-gradient(to right, magenta, red, orange, yellow, green, blue, purple);
}
This works fine, my question is about the background-color: nth($gradients, 1);is this a index that starts with 1 and is it used as a color-start?
Can someone explain?
Thanks :)
Yes,nth(gradients,1) picks the first element from the gradients list
so it would background-color:magenta here
for more explanation this
As you suspected, nth($gradients, 1) picks the first item from $gradients as Sass lists are 1-indexed.
In this case background-color is set to the first colour from gradients. You can think of this as a fallback in case the user's browser doesn't support linear-gradients.

Random color from array in Sass [duplicate]

This question already has an answer here:
SASS: randomly pick background-image from a list
(1 answer)
Closed 7 years ago.
I want to specify an array of colours and then apply the colors randomly to a list.
So far I have it so that the colors will cycle through in order.
How can I randomise it?
Here is the Sass code so far:
$colors: red, orange, yellow, green, blue, purple;
#for $i from 1 through length($colors) {
li:nth-child(#{length($colors)}n+#{$i}) {
background: lighten(nth($colors, $i), 20%);
}
}
li {
list-style: none;
padding: 1em;
}
and the markup:
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
<li>i</li>
<li>j</li>
<li>k</li>
<li>l</li>
</ul>
Example on Codepen:
http://codepen.io/anon/pen/azbwJm
Edit: Sass introduced a module system. The random() function is transitioning to math.random(). See the documentation for the function and for the module system for more information.
First, I should state a reminder to everyone reading that Sass is precompiled into CSS; you cannot achieve random behavior "at runtime" (i.e. on page load) using Sass.
Sass has a random() function that might interest you:
$colors: red, orange, yellow, green, blue, purple;
$repeat: 20 // How often you want the pattern to repeat.
// Warning: a higher number outputs more CSS.
#for $i from 1 through $repeat {
li:nth-child(#{length($colors)}n+#{$i}) {
background: lighten(nth($colors, random(length($colors))), 20%);
}
}
li {
list-style: none;
padding: 1em;
}
This chooses a random index of your $colors array and uses the associated color.
Note: the documentation states that random($limit) "returns a random whole number between 1 and $limit." This includes $limit as a possible value. As a result, if you use nth($colors, random(length($colors) + 1)), you are liable to get an error for using an index out of bounds.

Check if SASS parent selector exists. Is it possible

I have a question. So in a mixing I am making a reference to the parent selector "&". This works as long as the mixin is not nested. Is there a way to to detect if the mixing is being used in a non nested scenario, or to check if "&" is null?
This works when the mixin call is not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
#content
This works great when the mixin call is nested, but will not resolve '&' when not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
.classInHTMLToAllowMediaQueries &
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
.classInHTMLToAllowMediaQueries &
#content
So the question is, if there is a way to be able to check the value of parent selector "&", so I can cover all bases in a single mixin?
#mixin does-parent-exist {
#if & {
.exists & {
color: red;
}
} #else {
.doesnt-exist {
color: red;
}
}
}
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-script
You're trying a wrong solution to solve your issue.
Have a look at how this problem is addressed in powerful SASS frameworks. Let's take Susy by Eric Meyer as a great example.
Let's imagine you've got the following HTML:
<div class="container">
<div class="parent">
<div class="child">
Bla bla
</div>
</div>
</div>
When you call a mixin for the first time, you're doing it simply (the code is in the indented .sass syntax):
$total-columns: 8 // Declaring a varible that will be used by the mixin
.parent
+span-columns(4) // Span four of eight columns
But when you call that for a child element, the proportions would be crooked, because the parent is already proportioned:
.child
+span-columns(2) // This will fail. You want 2 of 8 columns,
// but due to nesting the math is crooked.
// It will be "2 of (4 of 8)".
To address the issue, you provide an optional argument: a context that is used to do the math:
.child
+span-columns(2, 4) // Now the mixin will take 2 parts of 4
// instead of 2 parts of four
The source code for this mixin is available on GitHub.
In short, it creates an optional argument like this (the code is in the CSS-like .scss syntax):
#mixin span-columns(
$columns,
$context: $total-columns
//...
) {
//...
width: columns($cols, $context /*...*/);
//...
}
See how $context has a default value? Thanks to the default value this argument can be omitted. In other words, $context is an optional argument.
When calling this mixin, if $context is not provided (e. g. span-columns(2)), then it is set equal to $total-columns. The $total-columns variable should be set prior to calling the mixin for the first time (see my example above).
Then the two arguments are used to calculate the width.
UPD 2013-03-30
I am not trying to figure out things in regards to columns... I have modifier my question to make it clearer.
First of all, my recommendation concerns not only grid columns. It's a universal technique you can adopt.
Secondly, now i see that you're trying to nest media queries.
Well, some media queries of different type can be combined in CSS3: e. g. print and width. But you can't put a min-width: 601px inside max-width: 600px, this just won't work!
There's an extensive answer here on StackOverflow describing why you should not nest media queries of the same type: https://stackoverflow.com/a/11747166/901944
Thirdly, you're trying to invent the wheel. There's already a fantastic mixin for crunching media queries: Respond To by Snugug. It's super easy to use and very effective.
Fourthly, the XY thing. Instead of asking about your crooked mixin, please describe the problem that you're trying to solve with it! Show us the actual HTML and explain what behavior you would like to achieve.
We will show you that it can be solved with a simple, elegant, semantic solution that does not require SASS hacking.

Sass calculate percent minus px

I want to be able to do the following:
height: 25% - 5px;
Obviously when I do that I get the error:
Incompatible units: 'px' and '%'.
Sass cannot perform arithmetic on values that cannot be converted from one unit to the next. Sass has no way of knowing exactly how wide "100%" is in terms of pixels or any other unit. That's something only the browser knows.
You need to use calc() instead. Check browser compatibility on Can I use...
.foo {
height: calc(25% - 5px);
}
If your values are in variables, you may need to use interpolation turn them into strings (otherwise Sass just tries to perform arithmetic):
$a: 25%;
$b: 5px;
.foo {
width: calc(#{$a} - #{$b});
}
There is a calc function in both SCSS [compile-time] and CSS [run-time]. You're likely invoking the former instead of the latter.
For obvious reasons mixing units won't work compile-time, but will at run-time.
You can force the latter by using unquote, a SCSS function.
.selector { height: unquote("-webkit-calc(100% - 40px)"); }
$var:25%;
$foo:5px;
.selector {
height:unquote("calc( #{$var} - #{$foo} )");
}
IF you know the width of the container, you could do like this:
#container
width: #{200}px
#element
width: #{(0.25 * 200) - 5}px
I'm aware that in many cases #container could have a relative width. Then this wouldn't work.
Sorry for reviving old thread - Compass' stretch with an :after pseudo-selector might suit your purpose - eg. if you want a div to fill width from left to (50% + 10px) of screen you could use (in SASS indented syntax):
.example
background: red
+stretch(0, -10px, 0, 0)
&:after
+stretch(0, 0, 0, 50%)
content: ' '
background: blue
The :after element fills 50% to the right of .example (leaving 50% available for .example's width), then .example is stretched to that width plus 10px.
Just add the percentage value into a variable and use #{$variable}
for example
$twentyFivePercent:25%;
.selector {
height: calc(#{$twentyFivePercent} - 5px);
}

Resources