Dividing percentage variable in Sass? - sass

I have a variable which is a number and a % eg 10%. How can I use it as a value in my SASS but apply a division on it?
I have this:
$value: 0.1;
$value-percent: $value * 1%;
$value-from-50: (50 - $value) * 1%;
.test {
padding-left: $value-percent;
}
.test2 {
width: $value-from-50;
}
Which outputs this:
.test {
padding-left: 10%;
}
.test2 {
width: 40%;
}
What I now need to do is apply half of the value of $value-percent:
.test3 {
padding-left: $value-percent / 2;
}
So that I can output:
.test3 {
width: 5%;
}
Ive tried various combinations of that example code with normal and curly brackets. I can get the correct number of 10 outputted into the CSS but the % is always missing from it.

If your initial var isn't a percentage and is just a number you may need to try this:
.test {
padding-right: ($var / 2) + 0%
}
Which is better practice as it'll convert the value you pass it into what you're adding it to, in this case a percentage.

Related

Sass manipulate with #content

Is it possible to manipulate with #content magic variable in SASS?
I would like to replace some stuff in here before output.
Or maybe can I fill some variable with it?
The conclusion is that, I want to make an mixin #important that create both versions. Important, and no-important.
Input
.test {
#include important {
color: red;
text-align: left;
}
}
Expected output
.test {
color: red;
text-align: left;
}
.test-i {
color: red !important;
text-align: left !important;
}
No, you can't. But I quickly wrote you a mixin to make it work. It doesn't accepts multiple properties (yet).
First Note: I changed the mixin it now does accept multiple properties. Here is the Codepen.
Second Note: I updated the mixin adding multiple properties does no longer compile to different classes for each property, instead you get two versions, one without the !important suffix and one with.
This is the mixin:
#function return($state) {
#return if($state == '', '', '-i');
}
#mixin loop($name, $items...) {
#each $item in $items / 2 {
#each $state in ('', '!important') {
$suffix: return($state);
.#{$name}#{$suffix} {
#for $i from 1 through (length($items) / 2) {
#{nth($items, ($i * 2) - 1)}: #{nth($items, ($i * 2))} #{$state};
}
}
}
}
}
This is how you include it:
// #include loop([classname], [property], [value]);
#include loop(whateverClassname, color, red);
This is what it compiles to:
.whateverClassname {
color: red ;
}
.whateverClassname-i {
color: red !important;
}
This is what it now compiles to, when you use multiple properties at once:
#include loop(whateverClassname, color, red, background-color, green, display, flex);
.whateverClassname {
color: red ;
background-color: green ;
display: flex ;
}
.whateverClassname-i {
color: red !important;
background-color: green !important;
display: flex !important;
}
Conclusion: it works as expected and does no longer bloat your CSS.
Hope I could help you at least a little ;-)

SASS Multiplication with units

If I try to multiply two value with units I get an unexpected error.
$test: 10px;
.testing{
width: $test * $test;
}
result: 100px*px isn't a valid CSS value.
I have used interpolation in the past when I want to do math with variables, and I think it is the simplest solution. If this doesn't work for you, perhaps it is due to a difference in compilers?
$test: 10px;
.testing{
width: #{$test * 2};
}
In fact width: $test * 2; compiles to width: 20px for me, you don't even need to use interpolation for simple math. I am using ember-cli-sass, which uses broccoli-sass-source-maps, which uses node-sass, which wraps libsass, to compile my SCSS to CSS. But it seems to work fine in this jsbin which uses SCSS with Compass.
Where interpolation really helps is if you need to use calc.
$test: 10px;
.testing{
width: calc(50% + #{$test * 2}); // results in calc(50% - 20px)
}
Multiplying units in SASS works like multiplying units in physics / engineering / chemistry / [insert science here].
(see more about this at https://www.sitepoint.com/understanding-sass-units/)
Multiplying two pixel values, will get you px^2, which is an area, not a distance.
What can you do? If you are certain you will be multiplying pixels, use a function and divide by 1 pixel.
$test: 10px;
#function multiply-px($value1, $value2) {
#return $value1 * $value2 / 1px;
}
.testing {
width: multiply-px($test, $test);//100px
}
If you don't know which units you'll be using in advance, you can strip the units from $value2, such that you always get the units of $value1.
(read more on that at https://css-tricks.com/snippets/sass/strip-unit-function/)
$test: 10in;
#function strip-unit($number) {
#if type-of($number) == 'number' and not unitless($number) {
#return $number / ($number * 0 + 1);
}
#return $number;
}
#function multiply-use-first-unit($value1, $value2) {
#return $value1 * strip-unit($value2);
}
.testing {
width: multiply-use-first-unit($test, $test);//100in
}
//try this
$test: 10;
.testing{
width: $test * $test px;
}
You cannot multiply two px values. Better way of doing it is function, but you have to use add in it to achieve it: -
$test: 10px;
#function calc-width($value1, $value2) {
#return $value1 + $value2;
}
.testing {
width: calc-width($test, $test);
}

Is it possible to concatenate two siblings without parent in Sass?

What I want is concatenate two child inside the parent but without choosing the parent on output.
What I mean is here:
.parent {
.child {
color: green;
& + & {
margin-top: 6px;
}
}
}
On the output I have this:
.canvas-btn .canvas-btn__icon + .canvas-btn .canvas-btn__icon {margin-top: 6px;}
but if it's possible to make the next way without duplicating the code is Sass?
.canvas-btn .canvas-btn__icon + .canvas-btn__icon {margin-top: 6px;}
You need to use the parent selector (&) as a variable here and treat it like the list of lists that it is:
#function nest-adjacent-selector($sel) {
$new-sel: ();
#each $s in $sel {
$last: nth($s, -1);
$new-sel: append($new-sel, $s #{'+'} $last, comma);
}
#return $new-sel;
}
.parent {
.brother, .sister {
color: green;
#at-root #{nest-adjacent-selector(&)} {
margin-top: 6px;
}
}
}
Output:
.parent .brother, .parent .sister {
color: green;
}
.parent .brother + .brother, .parent .sister + .sister {
margin-top: 6px;
}
Note that this will not work if you're using certain versions of LibSass. For more information on how this works, see this question.

How to preserve units with SASS computed variable?

I try to create some relative font-size values that match "nearly" pixels sizes:
html { font-size: 62.5%; }
$font-10px: 1em/1.1em;
$font-11px: 1.1em/1.1em;
$font-12px: 12em/11em;
.x10 { font-size: $font-10px; }
.x11 { font-size: $font-11px; }
.x12 { font-size: $font-12px; }
However, the output of this sass snipet is:
.x10 {
font-size: 0.90909;
}
.x11 {
font-size: 1;
}
.x12 {
font-size: 1.09091;
}
As you can see, the unit (em) has been stripped.
This results in a incorrect value.
How should I declare my variables to contains the correct unit?
Dividing one length by another length always results in the unit being removed if the lengths are using the same units. So your options are:
Divide using one length and one integer: 1.1em / 1.1
Multiply the unit back on afterwards: 1.1em / 1.1em * 1em
Don't use division at all: 1em
Add PX to the end of your variable and surround the variable with #{ }. This is known as interpolation #{ } and treats the variable as plain css. Interpolation also helps to remove any spaces between the number and unit of measurement:
$base-font-size: 16;
body { font-size: (62.5% * base-font-size); }
$font-10px: 1em/1.1em;
$font-11px: 1.1em/1.1em;
$font-12px: 12em/11em;
.x10 { font-size: #{$font-10px}px; }
.x11 { font-size: #{$font-11px}px; }
.x12 { font-size: #{$font-12px}px; }
Result:
.x10 {
font-size: 0.90909px;
}
.x11 {
font-size: 1px;
}
.x12 {
font-size: 1.09091px;
}
Since you mentioned accessability in the SA talk, I recommend that you add one of the mixins in this blog post by Hugo Giraudel to your project to allow the use REM units while also providing backwards compatibility for older browsers.

Sass loop: start from second instance of this element

I have a series of divs in a step type layout. I am learning to use Scss at the moment and I thought maybe a mixin could work through the 12 divs and arrange them for me. So far I've got:
#mixin steps(){
$stepBlocks: 12;
#for $i from 1 through $stepBlocks {
.steps-#{$i} {
position: absolute;
top: (($i * 296) + px);
display: block;
}
}
}
This is what my div structure looks like:
I've made a HTML mockup as well:
http://jsfiddle.net/vdecree/CGGyL/
As you can see, the fiddle works fine, however how can I negate the effect of the first one? I need the first element to be top: 0; is there an if statement I can use? If you think you've a better way in which I can do this, I'd appreciate any help.
What you're likely wanting to is start with an offset of 0, rather than 296px.
#mixin steps(){
$stepBlocks: 12;
#for $i from 1 through $stepBlocks {
.steps-#{$i} {
position: absolute;
top: ($i - 1) * 296px;
display: block;
}
}
}

Resources