LESSCSS: Assign a value to a property taken from another one's - less

In some cases is common to use same values in different properties, for example (is just an example to show purpose) the following nested rule:
.button-link
{
height:40px;
a
{
line-height:40px;
}
}
The idea is that to vertically center button text line-height and height should be equal.
Is there a way in LESS to "assign a value taken from a diffent property"?
I know that I should use a LESS #variable but in this case is not the same thing and need extra code. Instead should very interesting and useful if I should edit only button's height and then LESS will replaced the same value to line-height
UPDATE:
Another example could be the following:
.button-link
{
color:white;
background:black;
&:hover
{
color:black;
background:white;
}
}
In which "hover" status should invert color and background-color comparing to default state.

This is possible starting with v3 of LESS! Here is the documentation on it.
The example use case they provide ends up with the background-color getting the same value as the color property when compiled:
.widget {
color: #efefef;
background-color: $color;
}

You can´t :(. What i usually do is:
#buttom-height = 100px;
#a-link-height: #buttom-height;
and use that variables in your less declarations. Its a dummy example, i know, but imagine calculated data values from other variables or complex dependencies, proportional paddings/margins... that´s the way i learnt from Bootstrap LESS code.

Related

Less: Combining selector variables

Given i want to simplify the following LESS code:
#title1: ~"h1.someclass > a";
#title2: ~"h1.otherclass > a";
#{title1},#{title2} {
&:after {
display: none;
}
}
which evaluates to:
h1.someclass > a:after,
h1.otherclass > a:after {
display: none;
}
I tried to merge the classes by using
#titles: ~"#{title1},#{title2}"; // Combine selectors for easier code
#{titles} {
&:after {
display: none;
}
}
This however will yield different CSS.
h1.someclass > a,h1.otherclass > a:after {
display: none;
}
Is this due to the Lazy Evaluation of the variables? If so, why does it yield the CSS this way? And is there a diffrent way of combining selector variables and later using &:after?
(almost copy-pasting from the more wide https://stackoverflow.com/a/23954580/271274)
There're two problems with your attempt:
By definition a content of escaped strings is not a subject for any kind of evaluation at all, so commas (as well as any other special ops) have no meaning there.
Variable interpolation in selectors assumes a single interpolated variable contains only a single selector element. So, strictly speaking, even ~"h1.someclass > a" is already nothing but a hack expected to have side-effects and unspecified/undefined behaviour for anything but extremely trivial cases.
So in your code above the value of #titles works just as a simple/single selector element (the same as body for example).
I.e. in summary and in general, "string-based selector manipulation" (like ~"#{title1}, #{title2}") should be avoided where possible simply because in Less selectors are not strings and strings are not selectors (nor they automatically converted to each other except in, yet again, certain extremely trivial cases).
So far the only non-hackish method to define a reusable list of selectors in Less is a mixin (mixins can be considered as "variables" too even if they have another syntax) that puts an arbitrary set of rules into a ruleset having the said list as its selector. E.g. for your example above it would be something like:
#title1: ~"h1.someclass > a";
#title2: ~"h1.otherclass > a";
.titles(#rules) {
#{title1}, #{title2} {#rules();}
}
// usage:
.titles({
&:after {
display: none;
}
});
Demo.

Is there a way to dynamically add a class to another class in LESS?

Here's my situation: I have a table in which every row has a glyphicon-remove button, which is used to deactivate a record. When the table is read, the deactivated record has an .inActive class, which our LESS uses to mark text as red and strikethrough in the table. Well, I also want the glyphicon-remove element to be disabled as well. So, in our LESS file for the inActive class, we have this:
#RedWarning: red;
.inActive td:not(.commandColumn) {
text-decoration: line-through;
color: #RedWarning;
}
What I want to do is something like:
.inActive .glyphicon-remove {
/* me.AddClass('.disabled'); */
}
So that, in the end, if the tr has the class inActive, every glyphicon-remove on that row automatically becomes glyphicon-remove disabled. I know that I can do this in jQuery, but we have all kinds of tables throughout the system, and I want to be able to just make the change in one place.
I was looking at the :extend functionality, or just inheriting the class like this:
.inActive .glyphicon-remove {
.disabled;
}
...but that returns errors saying that LESS can't find the .disabled class.

Include a less file and pass parameters

I have a common.less file, that implements the basic CSS for different skins:
#textColor: black;
#iconSize: 16px;
.container: {
color: #textColor;
background-color: white;
}
.icon: {
width: #iconSize;
height: #iconSize;
}
// note that #iconSize is also used in this file inside mixins
The plan is to use it like so skin_1.less:
#iconSize: 32px; // override the icon size
// but leave #textColor as default
#import "common.less";
.container: {
color: red;
}
// I would now have big icons and red text
So I would like to have a common style, that I can reuse and selectively override variables.
This does not ssem to work however. I think it's because imports are always moved to the top, so variables cannot be pre-defined.
(I also read that variables are rather constants, so that may be another problem.)
Anyway: is there a better pattern to solve my use case?
You don't need to split the files up, just override the variable after the import. Variables are always resolved as the last definition, even if it is after where it is used.

Optimise Sprite CSS for multiple images

Had a few problems getting background-image displaying in Firefox, I made it work but was surprised at how bloated the CSS became. It now works great, but I need to replicate base CSS code for multiple images.
Can anyone tell me if it is possible to optimise the CSS classes and minimise the amount of code. I cannot utilize the already used id's, and class='imga p0' doesn't work (where p0 just holds the background-position, becoming p1, p2, p3 .. for each image position).
Thanks in advance for any advice.
a.imga0 {background:url(../images/sprite.png) no-repeat;background-color:transparent;
display:block;width:24px;height:24px;background-position:-288px 0;} /* tick green */
a.imga1 {background:url(../images/sprite.png) no-repeat;background-color:transparent;
display:block;width:24px;height:24px;background-position:-312px 0;} /* cross grey */
a.imga2 { ..... and so on.
Edit:
So this should eliminate the repetition
/* template */
a.imag0, a.imag1, a.imag2 {
display: block;
width: 24px;
height: 24px;
background:url(../images/sprite.png) no-repeat;background-color:transparent;
}
/* specifications */
a.imag0 {
background-position:-288px 0;
}
a.imag1 {
background-position:-312px 0;
}
For one you could create a general selector
a {
background:url(../images/sprite.png) no-repeat;background-color:transparent;
display: block;
}
Which would apply the general style, such as the sprite image.
You could also create a separate class (specify more classes with spaces)
So for example, you could have
<a class="imag0 spriteclass">something</a>
<a class="imag1 spriteclass">something</a>
<a class="imag2 spriteclass">something</a>
And
a.spriteclass {
//again the template, such as the sprite and display type and width
}
Your second option is to list out the selectors you want the css to apply to,
a.imag0, a.imag1, a.imag2... {
// your general css
}
And then like above specify the specific sprite positions and details separately
Adding this just in case some one refers to this post later.
You can generate the most optimized CSS using this below tool.
http://www.spritecss.com/

Can a mixin refer to values in the calling selector?

For example, I would like to be able to do this:
.bigfirstletter(#mag) {
&:first-letter {
font-size: [get_original_font_size] + #mag;
}
}
But as far as I can see I have to do this, which is not as neat
.bigfirstletter(#fontsize, #mag) {
&:first-letter {
font-size: #fontsize + #mag;
}
}
Do I have an alternative? Thank you for your help.
damn it was simpler than I thought :)
.bigfirstletter(#mag) {
&:first-letter {
font-size: 1em * #mag;
}
}
1em will simply inherit whatever it is defined for element, and you just set your magnification. I changed the plus sign to multiply on purpose as with this you're going to have better control over font size - #mag=1.0 for same font size, #mag=1.5 for 50% bigger, and so on..
sorry about the answer below, for some reason I didn't see that you're using first-letter in the example provided (doh!)
take a look at :first-letter CSS pseudo class - here