Less.js: if #color = value do something - css

Lets asume that i have a variable:
#title: blue;
And i need to know if there is anyway with the iscolor function to do something if the value is blue.
For example, if #title = blue import a #mixin to a class called "mytitle"
Im not really understanding the iscolor function and behavior
Thanks in advance

If I understand your question correctly, what you are trying to do is extremely simple:
#title: blue;
.mytitle when (#title = blue){
/*Do stuff here*/
}
If #title's value is equal to blue, add styles to .mytitle

iscolor is not appropriate here - it simply evaluates a string and tells you if the string is a valid color string. So trying something like iscolor(#title) will return true regardless of the color (as long as #title contains a valid color string).
Update: I think you're looking for the Mixin Guard feature:
.mixin (#a) when (lightness(#a) >= 50%) {
background-color: black;
}
.mixin (#a) when (lightness(#a) < 50%) {
background-color: white;
}
.mixin (#a) {
color: #a;
}

Related

SASS Simple function to convert HEX color into RGB as a string without alpha

I am looking for simple function in SASS that simply convert HEX color into RGB as a string.
I was googling, but without lucky. Maybe because there is not any native function in SASS? Sure, there is rgba() function, but I dont wanna rgba( ... ) piece. Simply the RGB string.
Example
Input
$color-bg: #637b9a;
$color-bg-light: lighten($color-bg, 25%);
$color-bg-light-rgb: hex2rgb($color-bg-light); // Functon that I am looking for
:root {
--color-body-bg-light: $color-bg-light;
--color-body-bg-light-rgb: $color-bg-light-rgb;
}
body {
color: var(--color-body-bg-light);
background-color: rgba(var(--color-body-bg-light-rgb), 0.8);
}
Output
:root {
--color-body-bg-light: #237b9a;
--color-body-bg-light-rgb: 44, 123, 154;
}
body {
color: var(--color-body-bg-light);
background-color: rgba(var(--color-body-bg-light-rgb), 0.8);
}
You can write the function like this:
#use "sass:color";
#function hex2rgb($hex) {
#return red($hex), green($hex), blue($hex);
}
But the problem is sass could not parse the variables for html custom properties.
So this line --color-body-bg-light: $color-bg-light; won't work.
At the end, you will get this:
:root {
--color-body-bg-light: $color-bg-light;
--color-body-bg-light-rgb: $color-bg-light-rgb;
}
You can't do that with Sass but you can use JavaScript to get the desired result.

Passing conditions to mixins in LESS

First of all, I am using LESS 1.7 (and there is no way I can change it). I have the following if-mixin in my less file that is just supposed to set the property and its value if the condition is met:
.if(#condition, #property, #value) when (#condition){
#{property}: #value !important;
}
It works fine if I pass the condition as true/false like this:
.column-header {
font-family: 'Something';
.if(true, color, green);
}
However, I am not able to pass the condition as an expression. If I want to pass a comparison such as 2 > 1, I get a parsing error: expected ')' got '>'. Is this not supported (or was this not supported in 1.7)? Am I doing something wrong? Any workaround? Thanks!
Not shure it's possible to pass contions to mixin.
But you can just write code witout .if mixin:
.column-header {
font-family: 'Something';
& when (2 > 1) {
color: green;
font-size: 20px;
}
}

How to pass a variable to lightness($color)? SCSS

I want to create a function which will change color based on background-colorlightness(), but get an error
Argument $color of lightness($color) must be a color
When I setup color: set-color(#000000); everything is okay, but I need to setup varibable ($background-color). Is there is a way to achieve it?
#function set-color($color) {
#if (lightness($color) >= 50) {
#return #000;
}
#else {
#return #FFF;
}
}
$background-color: attr(data-color);
background-color: $background-color;
color: set-color($background-color);
From the code it looks like u are using data-color attribute is down tag.
Either add the attribute to proper element in html
Or hard code $background-color to some value
i.e. replace
$background-color: attr(data-color)
with
$background-color: #000000

Using a variable from list in a function in each - scss [duplicate]

I've got list of colors and I would like to use darken() on them like so:
$innerPagesBgColors: "#6B46C1", "#2980B9", "#FD5456", "#000";
.foo {
color: darken(nth($innerPagesBgColors, 3), 5%);
}
But I get this error:
$color: "#FD5456" is not a color for `darken'
I tried interpolating the nth() portion but that didn't help either.
The problem is that darken function requires a color as first argument and, instead, you're trying to pass a string.
type-of(#6B46C1); // returns color
type-of("#6B46C1"); // returns string
So you should remove all quotes in $innerPagesBgColors:
$innerPagesBgColors: #6B46C1, #2980B9, #FD5456, #000;
In my case I solved with this.
#each $name, $color in $set_colors{
// check type-of before
#if (type-of($color) == 'color'){
.color-#{$name}{
color: #{$color};
}
.background-#{$name}{
background-color: $color;
&:hover{
background-color: darken($color, 10%);
}
}
}
}

Defining Variable Variables using LESS CSS

Say I have three separate color schemes that are used on various pages in a site. Each color has a a light, medium and dark tint defined, and the color scheme is defined by a class in the body. Assume that the "red" color scheme is the default. Like this:
Color Definitions:
#red-lt: #121;
#red-md: #232;
#red-dk: #343;
#green-lt: #454;
#green-md: #565;
#green-dk: #676;
#blue-lt: #787;
#blue-md: #898;
#blue-dk: #909;
Basic Default Style Example
body { background-color: #red-dk;
#container { background-color: #red-md;
p { color: #red-dk; }
}
}
Different Color Scheme Style Example
body.green { background-color: #green-dk;
#container { background-color: #green-md;
p { color: #green-dk; }
}
}
I'd like to use variables so that I don't have to re-write all of the color variations for each scheme, so that I can just write something like this:
body.[color-var] { background-color: #[color-var]-dk;
#container { background-color: #[color-var]-md;
p { color: #[color-var]-dk; }
}
}
…but I can't quite wrap my head around how to accomplish that. Help…?
Use interpolation and escaping, parentheses in the selector and parametric mixins to get the desired effect:
Dynamic variables by interpolation: In a string, "#{variable}" is replaced with the value of the variable. They can also be nested: Given #{#{var}-foo} and #var: bar;, the result is "barfoo".
The resulting value is quoted. To remove these quotes, prefix ~.
Dynamic selectors by Selector interpolation: body.#{var} turns into body.bar.
Example:
#red-md: #232;
#red-dk: #343;
.setColor(#color) {
body.#{color} { background-color: ~"#{#{color}-dk}";
#container { background-color: ~"#{#{color}-md}";
p { color: ~"#{#{color}-md}"; }
}
}
}
.setColor(~"red"); // Escape to prevent "red" turning "#FF0000"
//.setColor(~"blue"); etc..
Turns into:
body.red {
background-color: #334433;
}
body.red #container {
background-color: #223322;
}
body.red #container p {
color: #223322;
}
Note: When the answer was originally written, selector interpolation did not exist. See the previous revision for the solution if you're working with an old LESS compiler (before LESS 1.3.1a). Support for the old method will be dropped in LESS 1.4.0.
If those values really follow a predictable format like that, seems like a perfect case for a parametric mixin:
Less:
#red: #232;
#green: #565;
#blue: #898;
.theme (#color) {
background-color: #color - #111;
#container {
background-color: #color;
p { color: #color + #111; }
}
}
body.red {
.theme(#red);
}
Compiled CSS:
body.red{background-color:#112211;}
body.red #container{background-color:#223322;}
body.red #container p{color:#334433;}
I know this question is pretty old, but for those that come to this post my answer maybe can help
I`m not really sure for what you want to use this, but one of my suggestion is based on #ScottS answer. On my real world, I need to create a web app, where it would show several brands and each brand have their own text color, background and so on... so I started to chase a way to accomplish this in LESS, what I could easily do on SASS and the result is below:
LESS
// Code from Seven Phase Max
// ............................................................
// .for
.for(#i, #n) {.-each(#i)}
.for(#n) when (isnumber(#n)) {.for(1, #n)}
.for(#i, #n) when not (#i = #n) {
.for((#i + (#n - #i) / abs(#n - #i)), #n);
}
// ............................................................
// .for-each
.for(#array) when (default()) {.for-impl_(length(#array))}
.for-impl_(#i) when (#i > 1) {.for-impl_((#i - 1))}
.for-impl_(#i) {.-each(extract(#array, #i))}
// Brands
#dodge : "dodge";
#ford : "ford";
#chev : "chev";
// Colors
#dodge-color : "#fff";
#ford-color : "#000";
#chev-color : "#ff0";
// Setting variables and escaping than
#brands: ~"dodge" ~"ford" ~"chev";
// Define our variable
.define(#var) {
#brand-color: '#{var}-color';
}
// Starting the mixin
.color() {
// Generating the loop to each brand
.for(#brands); .-each(#name) {
// After loop happens, it checks what brand is being called
.define(#name);
// When the brand is found, match the selector and color
.brand-#{name} & {
color: ##brand-color;
}
}
}
.carColor {
.color();
}
Te result will be:
CSS
.brand-dodge .carColor {
color: "#fff";
}
.brand-ford .carColor {
color: "#000";
}
.brand-chev .carColor {
color: "#ff0";
}
This is very tricky and I had to use several elements to get what I needed, first used a set of mixins provided by Seven Phase Max and you can find it here and than, the #ScottS answer was the piece that was missing fro my puzzle... hope this helps you and others that need to create a set of Variables to be part of another variable and create a more dynamic less file.
You can copy my entire code and test at http://lesstester.com/
Try this
#red-lt: #121;
#red-md: #232;
#red-dk: #343;
#green-lt: #454;
#green-md: #565;
#green-dk: #676;
#blue-lt: #787;
#blue-md: #898;
#blue-dk: #909;
#color: 'red-lt';
div{
background: ##color;
border: 1px solid lighten(##color,20%);
}
To my knowledge, variable variable names are not supported in LESS. You could however restructure your declarations in a more semantic manner:
/* declare palette */
#red-lt: #121;
#red-md: #232;
#red-dk: #343;
#green-lt: #454;
#green-md: #565;
#green-dk: #676;
#blue-lt: #787;
#blue-md: #898;
#blue-dk: #909;
/* declare variables based on palette colors */
#lt: #red-lt;
#md: #red-md;
#dk: #red-dk;
/* ...and only use them for main declarations */
body { background-color: #dk;
#container { background-color: #md;
p { color: #dk; }
}
}
This should let you switch between palettes quite painlessly by avoiding explicit color references.

Resources