How to imitate arrays using less guards? - less

Is it possible to do something like this?
Or maybe is there a simpler and adequate «sugar» solution?
.bd (#border:0, #style:[solid,double,dotted]){
border: #border * 1px #style;
}
.dummy-style{
.bd(1, #[3]); //border: 1px dotted;
}

You don't need to imitate arrays because arrays do already exist in Less (they just do not have [] operator since it's already has another semantics in CSS).
.bd(#border, #style) {
border: #border * 1px extract(solid double dotted, #style);
}
.dummy-style {
.bd(1, 3);
}
(I'm not counting that:)
It's not a "sugar" in any way. Many people would consider this as antihuman cryptographic obfuscation: when anyone but you sees .bd(1, 3) how can she know what the heck this is supposed to mean at all? But of course it's completely up to you to decide if you're fine with "write-only" code.

Related

Intellij setting code columns with shortcut key

Is there some way in IntelliJ to define a shortcut key to auto-indent key - value pairs?
Instead of this:
form {
position: relative;
display: table-cell;
vertical-align: middle;
outline: 0;
border-radius: 4px;
}
I very much prefer this:
form {
position: relative;
display: table-cell;
vertical-align: middle;
outline: 0;
border-radius: 4px;
}
Note:
I'm quite peculiar about the formatting of my personal code (hobby project) and spend a good amount making it as readable as possible. I'm also a bit concerned someone may one day screw it up through a linter and auto-formatting during git commit.
If you have an alternate way of achieving this, I'd like to hear.
I apply the same formatting in JSX key-value pairs.
If not, I may have to write something myself.
I have a solution for you. For example if you are using .css file you should go:
setting -> Code style -> Style Sheet and choose Align valued option. (for you formatting it is Align value: On Values)
After applying your changes you could format your code with default format short cut: Command +alt + L for Mac and for widows ctrl + alt + l
I hope it is useful :)

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

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.

LESS CSS guards without mixin

I'm just getting into LESS and am trying to figure out how I can make conditional css statements without mixins. I find that I have a lot of single line css statements that only occur once but are dependent on some variable or condition and that using mixins is a bit pointless since it will never be reused.
Example.
#add-margin: true;
body {
margin-top: 20px; //I only want this if add-margin is true
}
So ideally I want this:
body when (#add-margin) {
margin-top: 20px;
}
But that doesn't work. Using a mixin works but seems silly to make one just for a one liner. Is there some alternative way I can do this?
Thanks
yes you can, it's similar to your code.
#add-margin: true;
.margin() when (#add-margin) {
margin-top: 20px;
}
body { .margin(); }
UPDATE: Using the latest versions of LESS (1.5+), usage of "guarded mixins" are not required to achieve this, and you could use "css gaurds" instead, therefore the OP's code will work out of the box
CSS Guards feature was introduced in Less v1.5.0 and hence now we can use guards the same way as mentioned in the question.
#add-margin: true;
body when (#add-margin){
margin-top: 20px;
}
If in case, you need to assign multiple such properties to different selectors based on the same variable, it can be implemented like below using the & selector.
& when (#add-margin){
body{
margin-top: 20px;
}
h1{
margin-top: 10px;
}
}
Note: As mentioned by memeLab in comments, any value for the #add-margin variable other than true are considered as falsy. This is because true is a keyword whereas 'true' is a String value. For example, the below would output nothing.
#add-margin: 'true';
body when (#add-margin){
margin-top: 20px;
}
However, the below would work because it does a String comparison.
#add-margin: 'true';
body when (#add-margin = 'true'){
margin-top: 20px;
}
If you are using Less compiler lower than v1.5.0 then the answer posted by Unicornist is the best bet.
no, it is not possible in that form.
you could use a variable equal to 0 or 1 and multiply by 20 and then always output a rule, or use JavaScript (i would advise you to avoid this) to convert true to 0 or 20 and always output a rule, but if you want the property added conditionally, you need guards.

Using a LESS variable as a property instead of a value

I've made the following two Mixins:
.responsive_color(#color, #response_color, #speed: 0.1s){
color: #color;
.transition(color, #speed);
&:hover, &:active, &:focus{
color: #response_color;
}
}
.responsive_background(#color, #response_color, #speed: 0.1s){
background-color: #color;
.transition(background-color, #speed);
&:hover, &:active, &:focus{
background-color: #response_color;
}
}
Since these two are nearly identical I want to combine them into something like this:
.responsive(#property, #color, #response_color, #speed: 0.1s){
#property: #color;
.transition(#property, #speed);
&:hover, &:active, &:focus{
#property: #response_color;
}
}
While this doesn't cause errors in the LESS parser (PHP class) it is simply ignored.
I've also tried #{property} and '#{property}' but both of these cause errors.
Does anyone know how I can output #property to be properly parsed?
Or am I trying to do something that isn't possible?
Just a quick update. Now the feature is there:
Properties can be interpolated, e.g. #{prefix}-property: value;
— Less.js 1.6.0 changelog
So if you're using Less 1.6 or later, now you can actually do it like this:
#{property}: #response_color;
More info in this great SO answer.
A similar question has been answered here that may help you. That particular feature isn't in the LESS.js framework (yet), but you can possibly get around it with a little hack, outlined here:
How to pass a property name as an argument to a mixin in less

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