I'm passing a list into a mixin to reduce the number of parameters I have to pass into my mixin. The mixin code can be seen below.
#mixin colorMedal($medalData) {
background-image: linear-gradient(
45deg,
nth($medalData,2) 0%,
nth($medalData,2) 50%,
nth($medalData,1) 50.1%,
nth($medalData,1) 100%
);
#{nth($medalData,0)} ~ .medal__ribbon--left {
background: nth($medalData,3);
}
#{nth($medalData,0)} ~ .medal__ribbon--right {
background: nth($medalData,4);
}
}
The list that im passing looks something like this
$platinum: ".medal__platinum", $medal-platinum, $medal-platinum-dark,
$medal-platinum-ribbon, $medal-platinum-ribbon-dark;
And the call of the mixin is :
#include colorMedal($platinum);
The code that seems to be causing a compile error is
#{nth($medalData,0)}
There must be a way to do this since you can pass in multiple values on their own. Is there a way to use a value from a list as a selector?
sass list starts at index 1 not 0
so change this from
#{nth($medalData,0)}
to
#{nth($medalData,1)}
you can debug the changes in codepen
https://codepen.io/srajagop/pen/wvBrzjO?editors=0102
Related
In my project I have a CSS custom variables like this:
:root {
--primary-color: #e04c4c;
--secondary-color: #2c2c5e;
--text-color: #d67900;
}
In my LESS files I have used LESS color functions to get more colors base on its primary and secondary. This is how its look like:
.component1 {
background: darken(--primary-color, 10%);
}
.component2 {
background: lighten(--secondary-color, 5%);
}
But when I compile this, it gives an error like this?
// Undefined_methodError: error evaluating function darken: //
Object # has no method 'toHSL'
When googling I found a solution for SASS, but not for LESS.
Can anybody tell me is there any possible workaround for this particular case?
Thank you.
I need to be able to use CSS variables because I need to have an hover effect (background-color) to be customizable by my VueJs app.
But my CSS stylesheet should have a default value, which is stored in a nested SCSS map. (map-getter is a function which returns values from nested maps)
I know that my SCSS code works, because I get the intended result when I do this:
.theme--dark .AppNavTile:hover {
background-color: map-getter($theme-dark, AppNav, hover);
//returns background-color: rgba(255, 255, 255, 0.87); in my browser's console
}
In order to use CSS variables, I can modify the code as follows:
.theme--dark .AppNavTile:hover {
--hover-bg-color: red;
background-color: var(--hover-bg-color);
}
It works fine and I have a red background when hovering the element.
Then I try to combine both:
.theme--dark .AppNavTile:hover {
--hover-bg-color: map-getter($theme-dark, AppNav, hover);
background-color: var(--hover-bg-color);
}
According to by browser's console, this returns the following:
.theme--dark .AppNavTile:hover {
--hover-bg-color: map-getter($theme-dark, AppNav, hover);
background-color: var(--hover-bg-color);
}
So it seems that the SCSS code remains uncompiled in the CSS variable. Is there any way around it?
Thanks!
The "problem" with CSS variables is they can have any value – why map-getter($theme-dark, AppNav, hover) is rendered as is. To instruct SCSS that this is actual SCSS code and not a random string you need to use interpolation (like if you use SCSS variables inside calc):
--hover-bg-color: #{map-getter($theme-dark, AppNav, hover)};
I wrote a class in LESS, which looks like this:
.horizontal-gradient (#startColor: #eee, #endColor: white) {
background: linear-gradient(red, yellow);
}
I tried to call it inside a LESS variable with this:
#primary-color: .horizontal-gradient(#35a1e5, #0172b9);
However, when running I get the error
NameError: variable #primary-color is undefined
But when I initialize the #primary-color as this:
#primary-color: #000;
Then it works just fine. So somehow, .horizontal-gradient class is causing the error.
DEMO I coudn't get LESS working within the SO fiddle. So I created a fiddle on jsFiddle.
http://jsfiddle.net/T2Xe9/828/
How can I use a LESS class inside a variable?
What you are using is not a variable, but a mixin: http://lesscss.org/features/#mixins-feature.
Without changing your .horizontal-gradient mixin, you can just use it:
div#background {
.horizontal-gradient(#35a1e5, #0172b9);
// The rest of your style
}
So: you cannot register a mixin result into a variable.
I want to be able to send in a few different colors and percentages, as a dynamic length list, to a LESS loop, to create a gradient. At the same time, I'd also like to prepend browser prefixes. The reason for this request is because I'm using CSS gradients in place of graphics for speed and minimizing requests.
Here's how I'm doing it now, but I'd like a more flexible solution:
.mkgrad(#gclrs, #gdir) {
#m:length(#list);
.looppref(#m, #j: 1) when (#j =< #m) {
#mypref: extract(#list, #j);
background:~"#{mypref}-linear-gradient(#{gdir}, #{gclrs})";
.looppref(#m, (#j + 1));
}
.looppref(#m);
.mkdir() when (#gdir = left) {
background:linear-gradient(to right, #gclrs);
}
.mkdir() when (#gdir = top) {
background:linear-gradient(to bottom, #gclrs);
}
.mkdir;
}
I'm calling this with the following:
#str1:fade(#cgray, 50%);
#str2:fade(#cwhite, 50%);
#str3:fade(#cblack, 50%);
#glist:#str1 0%, #str2 30%, #str3 100%;
background:#str3;
.mkgrad(#glist, left);
It's working, but I'd like to be able to merge the #str variables into the above loop so I can just send in a list of colors and percentages, and have it loop the list to build out a string for the background.
Can this be done? Is it possible using a mixin perhaps?
If I understand the goal correctly what you need is "Property Values Merge" feature so together with certain "Pattern-matching" optimizations the mixin could look like (assuming Less 1.7.x or higher, but I tested this only with v2):
// usage:
#gray: #010101;
#white: #020202;
#black: #030303;
#gradients: #gray 0%, #white 30%, #black 100%;
div {
.make-gradient(#gradients, left);
// or just:
// .make-gradient(#gray 0%, #white 30%, #black 100%; left);
}
// impl.:
.make-gradient(#gradients, #direction, #fade: 50%) {
background+: ~"linear-gradient(" #dir;
.loop(length(#gradients));
.loop(#i) when (#i > 0) {
.loop((#i - 1));
#gradient: extract(#gradients, #i);
#color: extract(#gradient, 1);
#stop: extract(#gradient, 2);
background+: fade(#color, #fade) #stop;
}
background+_:);
.dir(#direction);
.dir(#dir_) {#dir: #dir_}
.dir(left) {#dir: to right}
.dir(top) {#dir: to bottom}
}
I did not include any vendor prefixing because of tools like Autoprefixer (especially since it's now included as a plugin for Less v2), but I guess you'll easily add that yourself if you still find such kludge worthy.
P.S. As suggested in comments below: background+_:); works only in v2 (so it's more like an unintended bogus), more safe syntax is obviously background+_: ~")";
You could just use this mixin I created a few weeks back,
Rotatable Multi-stop SVG linear gradient mixin
It is as simple as
.multigradient(rgb; 168; #rgb; 2, 1); // id; degrees; colorstring; ratio
once you've built your colorstring, e.g.
#rgb: red 0, green 50%, blue 100%;
If you look at the code in this mixin, there is a function which builds an svg 'colorstop' string by looping through multiple values.
I have this little mixin set up:
.linear-gradient(#direction:top, #color1:#fff, #color2:#000)
{
background-image: -webkit-linear-gradient(#direction, #color1, #color2);
}
Then, in my main.less I'm trying something like this:
a { .linear-gradient(top, #999, #666); }
That works fine, by say I want to do something like this:
a { .linear-gradient(top, , #666); }
Now, the first color should default to its default mixin color. How do I do this? Is this even possible
You can also explicitly pass the arguments, where the remaining arguments assume their default values.
a { .linear-gradient(#direction:top, #color2:#666); }
Less isn't quite that clever. You can either be explicit:
.linear-gradient(top, #fff, #000);
or use a variable as an abstraction to pass in the defaults.
#colorVar1: #fff;
.linear-gradient(top, #colorVar1, #000);
Less doesn't know how to handle an empty space, and will treat is as invalid.