Is it possible to manipulate css variables using LESS? - less

With preprocessor variables it's easy to set up one variable and manipulate it so that I can use it to set multiple properties. (demo)
While experimenting with native css variables, I noticed that I could combine them with preprocessor variables, so in the following example: (use firefox)
h1 {
--length: 40px;
#length: var(--length);
line-height: #length;
border: 5px solid tomato;
}
line-height was correctly rendered at 40px
But, when I tried to manipulate the preprocessor variable - like this:
h1 {
--length: 40px;
#length: var(--length);
#length2: #length*2;
line-height: #length;
padding: #length2;
border: 5px solid tomato;
}
... the code failed.
Is this possible somehow?

As mentioned in my comment, my understanding of CSS variables is that the variable is resolved into its actual value by the UA. This happens after the Less compiler compiles the file and thus it wouldn't be aware of what is the actual value contained by the CSS variable.
To the compiler, the value of #length is only var(--length). Since this is not a number, an error is thrown during compilation indicating that the math operation is being done on an invalid type.
OperationError: Operation on an invalid type on line 4, column 3:
One way to fix this would be to make the Less compiler output the variable name as it is and have the multiplier appended to it (like string concatenation). This would then leave the control to the UA.
But since all CSS math operations have to be given within calc() function, the entire thing has to be wrapped within it. So, the below code would work fine.
h1 {
--length: 40px;
#length: var(--length);
#length2: ~"calc(#{length} * 2)";
line-height: #length;
padding: #length2;
border: 5px solid tomato;
}
Or, even the below would be enough if --strict-math is enabled during compilation:
h1 {
--length: 40px;
#length: var(--length);
#length2: calc(#length * 2);
line-height: #length;
padding: #length2;
border: 5px solid tomato;
}
Above code when compiled produces an output similar to the one in Example 11 of the specs and so it should be a reasonably good way of doing this :)
... Note, though, that calc() can be used to validly achieve the same thing, like so:
.foo {
--gap: 20;
margin-top: calc(var(--gap) * 1px);
}
var() functions are substituted at computed-value time...

Related

Is there a way to do relative (percentage or rem) line-height in styled-components?

Styled components claim to cover all of css but I've run into this simple but significant issue. I need to enlarge my line-height but in a relative way, otherwise the line gets cut (it's height is smalled than the letters).
When I try to use rem or % as unit, I get an error saying a number type is expected instead of a string.
line-height: 100% means 100% of the font size for that element, not 100% of its height. In fact, the line height is always relative to the font size, not the height, unless its value uses a unit of absolute length (px, pt, etc). another option which you can try is using table-cell
#wrapper{
height: 40px;
width:200px;
display: table-cell;
vertical-align: middle;
text-align: center;
background: red;
}

Conditional when in less-file

I am making a theme editor for WordPress, and would like to use less to build the CSS file.
I have put a string in a variable like this:
#banner-separation-style: 'thick_border';
Then I'm trying to use when() like this:
when (#banner-separation-style = 'thick_border') {
header {
... some style
}
... and some css selectors
}
I've also tried combinations without quoting the variable.
How do I properly create something similar to if-blocks with less?
Guards (when statement) can only be used along with a mixin or a CSS selector. We can't write a when statement without using one of those. So, either write it with a mixin like below:
#banner-separation-style: 'thick_border';
.border-styles() when (#banner-separation-style = 'thick_border') {
header { border: 2px solid red; }
nav { border: 2px solid green; }
}
.border-styles;
or directly with the CSS selector like below:
#banner-separation-style: 'thick_border';
header when (#banner-separation-style = 'thick_border') {
border: 2px solid red;
}
nav when (#banner-separation-style = 'thick_border') {
border: 2px solid green;
}
or atleast using an unnamed selector (&) like below:
#banner-separation-style: 'thick_border';
& when (#banner-separation-style = 'thick_border') {
header { border: 2px solid red; }
nav { border: 2px solid green; }
}
The first version (with mixin) is the one that I prefer because (a) you don't have to repeat the condition multiple times like in the CSS selector version and (b) giving the mixin a name makes it more readable than using an unnamed selector. It is just my choice and some other user could actually prefer the last because it doesn't need that extra mixin call statement.

Semantic-UI: Cheatsheet with all theme variables

As you can see at http://semantic-ui.com/usage/theming.html, there are predefined variables for each element, collection, module etc (for example button.variables: https://github.com/Semantic-Org/Semantic-UI/blob/master/src/themes/amazon/elements/button.variables).
Unfortunally, I cannot find all the possible variables for each element, module, collection etc. Is there something like a cheatsheet with all possible theme variables for Semantic-UI?
what you are actually looking for is Labeled as Definitions under the folder src.
https://github.com/Semantic-Org/Semantic-UI-Meteor-Data/tree/master/lib/semantic-ui/src/definitions
Here is an example: https://github.com/Semantic-Org/Semantic-UI-Meteor-Data/blob/master/lib/semantic-ui/src/definitions/globals/site.import.less
You can only change a few variable for each tag, for example for body:
body {
margin: 0px;
padding: 0px;
overflow-x: #pageOverflowX;
min-width: #pageMinWidth;
background: #pageBackground;
font-family: #pageFont;
font-size: #fontSize;
line-height: #lineHeight;
color: #textColor;
font-smoothing: #fontSmoothing;
}
Hope this helps you out!
Bests!
Jules

Why did bootstrap 3 make all my fonts smaller?

I am new to bootstrap, and I added bootstrap 3 into my project and it shrunk all the font sizes, I never had any font size specified in these classes. I thought bootstrap 3 had the default size to 14.. is there something else I need to do?
Thanks
It appears to be happening, at least as of version 3.3.6, due to this block on line 1097:
html {
font-size: 10px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
You can restore your font-size by adding this to your stylesheet:
html
{
font-size: 100%;
}
You can customize/override anything - if, for example, you load YOUR css file AFTER the bootstrap file, then your settings will override it. Whatever you can dream:
p {
font-size 18px;
}
and so on...
I strongly recommend digging into the source code: https://github.com/twbs/bootstrap/blob/master/dist/css/bootstrap.css
html {
font-size: 62.5%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.428571429;
color: #333333;
background-color: #ffffff;
}
UPDATE: TO clarify, "No" you shouldn't have to do anything else. It sounds like there is another problem. The linked source code has changed since the original answer date... as of Feb 2015, it looks like this:
html {
font-size: 10px;
}
body {
font-size: 14px;
}
Assuming we've set our project up correctly, (bower install bootstrap is pretty easy)... attempting to echo text outside of the body should result in 10px text, inside body should be 14px.
If you don't see 14 point text inside the body, then something else might be stepping on it. I'd next inspect in in Chrome (for example) to confirm where the font-size was coming from.
I'd like to add that I think it's helpful to understand how these values we see in this /dist/css file are derived from less variables... the defaults should work out of the box, but you have easy control over everything, including the body text size: see http://getbootstrap.com/css/#less-variables.

How to pass argument from mixin to another in lesscss?

I'm using the LESS CSS module 7.x-2.4 in Drupal 7.8
I would like to use style mixins which pass arguments to another mixin. In the example passing the color as a string "#CC00CC" works ok, but not as an variable like that "darken(#col, 10%)".
#bg(#colBg){
background-color: #colBg;
}
#style(#col){
border: 2px solid lighten(#col, 10%); // ok
#bg(#CC00CC); // ok - color is passed
#bg(darken(#col, 10%)); // Color is not being passed to #bg
}
.buttonSubmit{
#style(#FF00FF);
}
How can I achieve cascading variables from the css-class to a mixnin which passes the argument to another mixin?
Your syntax is incorrect. Check the docs on mixins. The code you have should be written like this:
.bg(#colBg){
background-color: #colBg;
}
.style(#col){
border: 2px solid lighten(#col, 10%);
.bg(#CC00CC);
.bg(darken(#col, 10%));
}
.buttonSubmit{
.style(#FF00FF);
}