struggling with sass each output is empty - sass

I'm about to try something pretty similar to this: https://stackoverflow.com/a/8380156/2309928
I've got this scss code:
$max-width: 95vw;
$max-height: 95vh;
$styleFactors: ("very-large": 1, "large": 0.75, "normal": 0.4, "small": 0.35);
#each $widthOrHeight in "width", "height"{
#each $style, $factor in $styleFactors {
$max-size: if($widthOrHeight == "width", $max-width, $max-height);
.#{$widthOrHeight}-#{$style} {
$style: calc(#{$max-size} * #{$factor});
}
}
}
expected output should look something like this:
.width-very-large{
width: calc(95vw * 1);
}
.width-large{
width: calc(95vw * 0.75);
}
.width-normal{
width: calc(95vw * 0.4);
}
.width-small{
width: calc(95vw * 0.35);
}
//...
//and same with height
but there is no output at all and I'm out of ideas why this is happening..
theres no error or anything
Try it out on Sassmeister

You do not actually apply any styles and empty styles are simply removed. If you add for instance #{$widthOrHeight}: $style; after $style: calc(#{$max-size} * #{$factor}); you will see an output.

updated Sassmeister:
fault was at line 17:
$max-width: 95vw;
$max-height: 95vh;
$styleFactors: ("very-large": 1, "large": 0.75, "normal": 0.4, "small": 0.35);
#each $widthOrHeight in "width", "height"{
#each $style, $factor in $styleFactors {
$max-size: if($widthOrHeight == "width", $max-width, $max-height);
.#{$widthOrHeight}-#{$style} {
#{$widthOrHeight}: calc(#{$max-size} * #{$factor});
}
}
}

Related

SASS mixin with if statements to handle conditions

I was writing a mixin in SCSS to handle a map (padding, margin, etc etc), but I am getting a little stuck with all the #if logic to get the proper output.
In my defaults.scss file I have 2 variable, $size and $prefixes:
$size: auto, 1, 2, 2\.5, 4;
$prefixes: (
padding: (
top: "pt",
right: "pr",
bottom: "pb",
left: "pl",
x: "px",
y: "py",
all: "p",
),
);
I created mixin.scss that would take in $sizes, $prefixes, and a $property (ie "padding") like:
#include mixer.create-space(
$sizes: $sizes,
$prefixes: $padding,
$property: "padding"
);
The $padding in this case was just assigned earlier with map.get like
$padding: map-get($prefixes, "padding");
I know I need to #each through the $sizes and #each through the $prefixes to assign the right values, but I am really getting lost in my conditions.
px and py need 2 properties each (left/right || top/bottom)
if $size == auto, only assign to px/py (Currently it is being added to every class)
#mixin create-space($sizes, $prefixes, $property) {
// $size => 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96
#each $size in $sizes {
// $alignment => "top", "bottom", "left", "right", "y", "x", "all"
// $prefix => "pt", "pr", "pb", "pl", "py", "px", "p"
#each $alignment, $prefix in $prefixes {
// If $alignments is x, then $property-left and $property-right
// If $alignments is y, then $property-top and $property-bottom
// If $alignments is all, then $property
// If $size is auto for $alignment top, right, bottom, left, then $property: auto
#if $alignment == "x" {
.#{$prefix}-#{$size} {
#{$property}-left: calc(($size * 4) / 16) + rem;
#{$property}-right: calc(($size * 4) / 16) + rem;
}
} #else if $alignment == "y" {
.#{$prefix}-#{$size} {
#{$property}-top: $size * 4;
#{$property}-bottom: calc(($size * 4));
}
} #else if $size == "auto" {
.#{$prefix}-#{$size} {
#{$property}: auto;
}
} #else if $alignment == "all" {
.#{$prefix}-#{$size} {
#{$property}: calc(($size * 4) / 16) + rem;
}
} #else {
.#{$prefix}-#{$size} {
#{$property}-#{$alignment}: calc(($size * 4) / 16) + rem;
}
}
}
}
}
My mixin does work, but I run into errors when I am trying to calc the $size into rems when I run into $size: auto etc. Really, it is just becoming a mess.
** Edit **
It really seems that the decimal numbers were throwing everything off in the long run.

How can I get responsive classes with this mixin

My sass file looks like this when I use my mixin:
$viewports: 25 50 75 100;
#each $viewport in $viewports {
.vh-#{$viewport} {
height: #{$viewport}vh;
}
}
.vh-25 {
height: 25vh;
}
...
But I want that class and the class with the #sm, #md, …
Can I do that with sass?
#media (min-width: 576px) and (max-width: 767px) {
.vh-25#sm {
height: 25vh;
}
}
# is not allowed in class name, but if you want to replace it with -:
$viewports: (
xs: 25,
sm: 50,
md: 75,
xl: 100,
);
#each $viewport, $height in $viewports {
.vh-#{$height}-#{$viewport} {
height: #{$height}vh;
}
}

SASS check if current loop contains part of input

I have an array called $ratings-list that I'm trying too loop through and if the $current-class contains .5 then to use a a segment of css otherwise use a different segment;
$ratings-list: 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5;
#each $current-class in $ratings-list {
$i: index($ratings-list, $current-class);
&[data-rating="#{$current-class}"] {
#if (index($current-class, .5)) {
.rating-stars__star:nth-child(-n+#{floor($current-class)}) .ratings-star {
height: floor($current-class);
}
} #else {
.rating-stars__star:nth-child(-n+#{$i}) .ratings-star {
height: 7px;
}
}
}
}
The above always returns the else height: 7px segment.
You could turn $current-class into a string and use str-index instead.
$ratings-list: 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5;
#each $current-class in $ratings-list {
$i: index($ratings-list, $current-class);
[data-rating="#{$current-class}"] {
#if (str-index(#{"" + $current-class}, '.5')) {
.rating-stars__star:nth-child(-n+#{floor($current-class)}) .ratings-star {
height: floor($current-class);
}
} #else {
.rating-stars__star:nth-child(-n+#{$i}) .ratings-star {
height: 7px;
}
}
}
}
Compiles to
[data-rating="1"] .rating-stars__star:nth-child(-n+1) .ratings-star {
height: 7px;
}
[data-rating="1.5"] .rating-stars__star:nth-child(-n+1) .ratings-star {
height: 1;
}
[data-rating="2"] .rating-stars__star:nth-child(-n+3) .ratings-star {
height: 7px;
}
[data-rating="2.5"] .rating-stars__star:nth-child(-n+2) .ratings-star {
height: 2;
}
[data-rating="3"] .rating-stars__star:nth-child(-n+5) .ratings-star {
height: 7px;
}
[data-rating="3.5"] .rating-stars__star:nth-child(-n+3) .ratings-star {
height: 3;
}
[data-rating="4"] .rating-stars__star:nth-child(-n+7) .ratings-star {
height: 7px;
}
[data-rating="4.5"] .rating-stars__star:nth-child(-n+4) .ratings-star {
height: 4;
}
[data-rating="5"] .rating-stars__star:nth-child(-n+9) .ratings-star {
height: 7px;
}

C3.js Donut Chart,Grow Segment

i'm exploring c3.js, i have created an donut chart, which was very simple to do, next thing i wanted to do is on mouser-over i wanted to expand/zoom/popout that focused segment, this functionality we can see in d3pai., but i'm trying to achieve this effect purely using c3.js.
can some one please suggest me how to proceed and how to create such poping-up of segment effect.
var init = function() {
var chart = c3.generate({
data: {
x: 'x',
columns: [
['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
['Coin1', 30, 200, 100, 400, 150, 250],
['Coin2', 130, 100, 140, 200, 150, 50],
['Coni3', 50, 100, 130, 240, 200, 150],
['Coin4', 130, 100, 140, 200, 150, 50],
['Coin5', 130, 150, 200, 300, 200, 100]
],
type: 'donut',
onclick: function(e) {
//console.log(e);
// console.log(d3.select(this).attr("stroke-width","red"));
},
onmouseover: function(d, i) {
},
onmouseout: function(d, i) {
}
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d',
centered: true,
position: 'inner-right'
}
}
},
bindto: '#dash',
bar: {
width: {
ratio: 0.5 // this makes bar width 50% of length between ticks
}
},
pie: {
expand: true,
},
tooltip: {
grouped: false,
contents: function(data, defaultTitleFormat, defaultValueFormat, color) {
// console.log("Containt");
// console.log(data, defaultTitleFormat, defaultValueFormat, color);
return "<p style='border:1px solid red;'>" + data[0].value + "</p>";
}
}
});
};
inti();
p {
line-height: 1;
font-weight: bold;
padding: 5px 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 4px;
line-height: 15px;
font-size: 12px;
min-width: 91px;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
</head>
<body>
<div id="dash"></div>
</body>
</html>
In the c3 config object, you can define onmouseover and onmouseout callback functions. The DOM node corresponding to the events is passed in as the second argument, so you can use it in the logic.
You can use that to apply things such as transformations. So on mouseover, you could scale it up, and on mouseout, scale it down. This is just a nudge in the right direction. You can play with other transformations to get the effect you want.
onmouseover: function (d, i) {
// 'i' is the dom node.
d3.select(i).attr("transform", "scale(1.1)")
},
onmouseout: function (d, i) {
d3.select(i).attr("transform", "scale(1)")
}
http://jsfiddle.net/ggamir/eqkrr5j0/
If you want the transformation to persist until the next mouse event, then you can keep track of the last item hovered over, and only "de-transform" it on the next mouseover:
http://jsfiddle.net/ggamir/79qhy9hn/
// Somewhere outside before defining your c3 config object:
var currentSlice;
// Inside your c3 config object:
onmouseover: function (d, i) {
if(currentSlice !== void 0) {
currentSlice.attr("transform","scale(1)")
}
currentSlice = d3.select(i).attr("transform", "scale(1.1)");
}

generate classes from Scss / Sass nested map

How does one generate a list of classes for each key that has a single value inside a Scss/Sass map?
For example, from this Scss map (disregard nested naming conventions, this will be used for many maps of varying purposes):
(See Codepen: http://codepen.io/harlanlewis/pen/emWVrr (thanks cimmanon!))
$palette: (
brown: hsl(33,35,50),
blue: hsl(207,80,50),
green: (
0: hsl(157,65,65),
1: hsl(157,50,50),
alt: (
0: hsl(125,65,65),
),
),
red: (
0: hsl(0,60,50),
alt: (
0: hsl(0,100,50),
),
),
yellow: (
0: hsl(50,100,60),
1: hsl(50,100,100),
),
};
-
#mixin map-to-class($map, $selector: '', $property: '') {
$selector: if($selector == '' and &, &, $selector);
#each $key, $value in $map {
#if type-of($value) == map {
$selector: selector-append($selector, #{$key});
#include map-to-class($value, $selector, $property) {
#content;
}
} #else {
#at-root #{$selector}#{$key} {
#{$property}: $value;
};
};
};
};
#include map-to-class($palette, '.u-fg__', 'color')
...desired classes to generate:
.u-fg__brown { color: hsl(33,35,50) }
.u-fg__blue { color: hsl(207,80,50) }
.u-fg__green0 { color: hsl(157,65,65) }
.u-fg__green1 { color: hsl(157,50,50) }
.u-fg__greenalt0 { color: hsl(125,65,65) }
.u-fg__red0 { color: hsl(0,60,50) }
.u-fg__redalt0 { color: hsl(0,100,50) }
.u-fg__yellow0 { color: hsl(50,100,60) }
.u-fg__yellow1 { color: hsl(50,100,80) }
The actual (incorrect) generated classes are: (note greenredyellow instead of just yellow)
... (brown, blue, and green are fine) ...
.u-fg__green0 { color: hsl(157,65,65) }
.u-fg__green1 { color: hsl(157,50,50) }
.u-fg__greenalt0 { color: hsl(125,65,65) }
.u-fg__greenred0 { color: hsl(0,60,50) }
.u-fg__greenredalt0 { color: hsl(0,100,50) }
.u-fg__greenredyellow0 { color: hsl(50,100,60) }
.u-fg__greenredyellow1 { color: hsl(50,100,80) }
What you're looking for is a recursive mixin. Walk through the mapping. If the value is a mapping, call itself otherwise print out the property/value.
$palette: (
'brown': hsl( 33, 35, 50),
'blue': hsl(207, 80, 50),
'green': (
0: hsl(157, 65, 65),
1: hsl(157, 50, 50),
alt: (
0: hsl(125, 65, 65),
),
),
'red': (
0: hsl(0, 60, 50),
alt: (
0: hsl(0, 100, 50),
),
),
'yellow': (
0: hsl(50, 100, 60),
2: hsl(50, 100, 100),
),
);
#mixin map-to-class($map, $property, $sel, $divider: '') {
$sel: if($sel == '' and &, &, $sel);
#debug $sel;
#{$sel} {
#each $k, $v in $map {
#at-root #{$sel}#{$divider}#{$k} {
#if type-of($v) == map {
#include map-to-class($v, $property, '', $divider) {
#content;
}
} #else {
#{$property}: $v;
}
}
}
}
}
#include map-to-class($palette, color, '.u-fg__', '');
Output:
/* line 33, ../sass/test.scss */
.u-fg__brown {
color: #ac8453;
}
/* line 33, ../sass/test.scss */
.u-fg__blue {
color: #198ae6;
}
/* line 33, ../sass/test.scss */
.u-fg__green0 {
color: #6ce0b3;
}
/* line 33, ../sass/test.scss */
.u-fg__green1 {
color: #40bf8e;
}
/* line 33, ../sass/test.scss */
.u-fg__greenalt0 {
color: #6ce075;
}
/* line 33, ../sass/test.scss */
.u-fg__red0 {
color: #cc3333;
}
/* line 33, ../sass/test.scss */
.u-fg__redalt0 {
color: red;
}
/* line 33, ../sass/test.scss */
.u-fg__yellow0 {
color: #ffdd33;
}
/* line 33, ../sass/test.scss */
.u-fg__yellow2 {
color: white;
}
Note that I quoted your mapping key names. Sass will convert those to their hex code equivalents under certain compression types.

Resources