less css variables with color name - css

I'm trying to create a few dynamics classes width Less css.
The idea is use in html this class:
.color-white{
color: white !important;
}
I created this sintaxis in Less:
.change-color(#which; #color){
.color-#{which}{
color:#color !important;
}
.background-#{which}{
background-color:#color !important;
}
}
So, with this I want to take my idea :D
.change-color(#which: white; #color: white);
But, that is the problem, I have this:
.color-#ffffff{
color:#fff!important
}
.background-#ffffff{
background-color:#fff!important
}
How can I use "white" as string and not as hex color.
Thanks.

Call this way instead:
.change-color(#which: ~'white'; #color: ~'white');
Though I think it would be better to just create a class called .color-red explicitly rather than make things more unreadable for little reason.

Related

Compass - include one value for another property

I want to include a value from another class - and use this for something different:
I have this class:
.sourceClass {
color: red;
}
And I have this class:
.destinationClass {
border-color: ###should be the color from .sourceClass => red
}
is this possible? And how can I do that?
You tagged your post with "Sass". Are you using the Sass/SCSS preprocessor? If so, you'd declare and use a variable like this:
$myColor: red;
.sourceClass { color: $myColor; }
.destinationClass { border-color: $myColor; }
If you're not using Sass, you can read about native CSS variables - which are currently working in Firefox and Chrome, but not IE/Edge.
Lastly, there is a possible solution supported in all current browsers, which would be applicable depending on your DOM hierarchy: currentColor.
If your .destinationClass is a child of .sourceClass, and therefore is inheriting color: red, you could simply use border-color: currentColor to take that color and use it as the border color.
Hope this helps!

LESS mixins vs classes

I'm looking into LESS because I definitely see some of their benefits. For instance colour declaration.
One thing I don't understand tho, and maybe I'm not getting the flow right is - why use the following LESS snippet
.radius {
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius:5px;
}
.btn-red{
background-color:red;
.radius;
}
.btn-green{
background-color:green;
.radius;
}
...
When we can use the .radius class in the html file right away. I'm left with the impression that LESS will add a ton of duplicate code once it gets compiled.
I'm using the following, which makes more sense. Same with font-size, margins, etc... Aren't classes used in such cases?
<div class="btn-red radius">Cancel</div>
<div class="btn-green radius">Go</div>
The snippet above does not benefit from SASS/LESS capabilities that much. Lets have a closer look and check this SCSS snippet.
// Abstract placeholder.
%radius {
border-radius: 5px;
}
// Put your global styling here.
// I'm assuming that you can alter the markup and have button.btn.btn-green
.btn {
// Color modifier.
&-red {
#extend %radius;
background-color: red;
}
&-green {
#extend %radius;
background-color: green;
}
}
The CSS output will be:
.btn-red, .btn-green {
border-radius: 5px;
}
.btn-red {
background-color: red;
}
.btn-green {
background-color: green;
}
And then you have to pick up Autoprefixer and vendor-prefixes issue is solved once and for all.
Because now, you can just specify the class btn_red or btn_green and all the buttons will automatically have a radius.
Your HTML should contain only the semantics, and styling or classes referring to styling should not be part of it.
That applies to the other classes as well. If for instance, you would rename btn_red to btn_cancel, you have a meaningful classname that you can apply to any kind of cancel button. And in the CSS you can specify that a cancel button is red and a 'Go' button is green, and both have a radius, without needing to modify the HTML at all.
So, the ultimate goal is to have the HTML describe the structure and the CSS describe how that structure should look. And a CSS preprocessor is only their to make a bulky spaghetti-like CSS file more structured.
There are several benefits.
You can use more semantic class names. Rather than encoding style information directly in your class names, (btn-red, radius) you could use a single class that conveys the usage of the style, rather than its contents.
You can avoid repeating yourself.
#radius-size: 5px;
-webkit-border-radius:#radius-size;
-moz-border-radius:#radius-size;
border-radius:#radius-size;
You can parameterize it so that you'd be able to use different radiuses (radii?) in different contexts.
.radius(#radius-size) { ... }
Because there are cases that developer has-no-access or don't-want to change the markup. and the only solution is to include all props from a predefined class.
for example:
you have bootstrap loaded (then you already have .has-success and .has-error classes) and if you want to use HTML5's native form validation using input's :valid and :invalid states, you have to use JavaScript to add/remove success/error classes based on input's states. but with this feature of LESS you can include all props of success/error class inside input's states. the code for this example could be something like this:
#myinput {
&:valid { .has-success; }
&:invalid { .has-error; }
}

Dynamic Variable Names in LESS CSS

I have been trying this for a while, looking at other answers, but to no avail. Hopefully someone can help me.
I am trying to generate some dynamic variable names within a mixin.
The variables are already defined:
#horizontal-default-color: #fff;
#horizontal-inverse-color: #000;
etc..
The mixin I want would be something like this:
.horizontal-variant(#variant) {
color: #{horizontal-#{#variant}-color}
}
And the result I am expecting, when called:
.horizontal-default{
.horizontal-variant(~"default");
}
.horizontal-inverse{
.horizontal-variant(~"inverse");
}
is
.horizontal-default {color: #fff}
.horizontal-inverse {color: #000}
Unfortunately I run into errors every time.
I know this can be done, I have seen it being used in Font Awesome LESS where #{fa-css-prefix} is defined in variables. I am just having trouble transporting the same solution in my project.
You can try testing the code at http://lesstester.com/
You can use Variable Names. And I've tested the code at http://lesstester.com/, it works.
#horizontal-default-color: #fff;
#horizontal-inverse-color: #000;
.horizontal-variant(#variant) {
#color: "horizontal-#{variant}-color";
color: ##color;
}
.horizontal-default{
.horizontal-variant(default);
}
.horizontal-inverse{
.horizontal-variant(inverse);
}

Updating a Variable through a Mixin

So lets say I set the background of 10 elements on the page to #base, then a user lands on the "Foo" page which has the class on the body of the page.
How does one update the #base via a css declaration? I understand that variables are local to a function (or css declaration) but there must be a method to do this! (would make styling alternative pages so easy!)
#base: #00000;
body.foo{
#base = #FFF;
}
LESS is a Preprocessor so...
...it all has to be precompiled into CSS ahead of time. That means all possible class combinations need to be made into valid CSS ahead of time. If you wanted something like this, you would need to do something like the following in your LESS:
LESS
#base: #000000;
.setColorOptions(#className: ~'', #base: #base) {
#classDot: escape(`('#{className}' == '' ? '' : '.')`);
#class: escape(#className);
body#{classDot}#{class} {
someElement {color: #base;}
.someClass {color: #base;}
// etc.
}
}
.setColorOptions();
.setColorOptions(foo, #fff);
.setColorOptions(bar, #ccc);
CSS Output
body someElement {
color: #000000;
}
body .someClass {
color: #000000;
}
body.foo someElement {
color: #ffffff;
}
body.foo .someClass {
color: #ffffff;
}
body.bar someElement {
color: #cccccc;
}
body.bar .someClass {
color: #cccccc;
}
Obviously if there were many elements and a lot of color dependent things going on, this could get big fast. Imagine 100 elements under body with three color variations as above, and you have 300+ lines of CSS, 200+ (two-thirds) of which do not apply to any one page. And this doesn't account for other changes, like background colors, etc. In such a case, it is best to set up different LESS files that import a different set of values for #base and build different style sheets to be loaded on the pages that need it. However, if you are just doing a small subset of color changes to a page, this could be a valid way to go.
There is no way to do that.
LESS has no way to know whether the selector body.foo will apply at compile time.

Can I create Less color themes with variables that rely on other variables?

Does anyone know how to do what I am attempting to do here?
#theme (dark) {#primary: black;}
#theme (light) {#primary: white;}
#theme (#_) {#primary: yellow;}
#name: dark;
#theme(#name);
.rule {
color: #primary;
}
I am trying to define a few "themes" which will have colors and images (possibly) that will be used throughout the various Less files. I have made do in the past with defining them globally and commenting out those that are not in use, but I am trying to see if there are people who have found better strategies in Less than what I have.
I had at one point found a feature that used to be (?) a part of Less but it doesn't seem to work.
.theme {
#color: red;
}
.rule {
color: .theme > #color;
}
This would be great, if it worked.
After a bit of messing with LESSCSS, I've come up with a reasonable way to change all variables based on a single #theme variable.
The trick is to use variable interpolation to specify a variable reference to a variable.
//this can be either "dark" or "light"
#theme: dark;
#theme-primary: "#{theme}-primary"; //this will evaluate to "dark-primary"
#theme-secondary: "#{theme}-secondary"; //this will evaluate to "dark-secondary"
#dark-primary: #F00;
#dark-secondary: #000;
#light-primary: #333;
#light-secondary: #FFF;
body {
//#theme-secondary evaluates to "dark-secondary"
//#dark-secondary evalutates to #000
background-color: ##theme-secondary;
//#theme-primary evaluates to "dark-primary"
//#dark-primary evaluates to #F00
color: ##theme-primary;
}
Older version
While I don't know of an easy way to conditionally define variables, if you're going to change one word and change a color theme, you might as well change an import statement:
#import ’themes/dark.less’;
//#import ’themes/light.less’;

Resources