Can I do math within a LESS css string interpolation?
Not Within the String Itself, but...
If you separate it out of the string, then do a second interpolation following (note the 2nd ~
), this works:
@tablet-landscape-only: ~"only screen and (min-width: "(@bp-tablet-portrait + 1) ~") and (max-width: @{bp-tablet-landscape})";
To produce this:
@media only screen and (min-width: 769px ) and (max-width: 1024px) {
div#header {
background: #000;
}
}
What is the right syntax for .less variable interpolation?
So if I understand correctly, you want to give the width
a value but without any units, and assign the units at the time of the call. I'm not sure why you would want to do that, but there are two ways that would work:
ONE: make the width
a string and then do a string interpolation:
@width: '600';
.some-style
{
width: ~'@{width}px';
}
TWO: multiply by 1px
:
@width: 600;
.some-style
{
width: @width * 1px;
}
I've left the above answers in place for a case of "unitless" numbers and how to add the unit later (as the question appeared to be at first). However, based on your comment let me explain why @width: 600px
works. LESS does not see that as a string (as you mention you view it). Rather, it sees it as a number with units. To LESS 600px
is not the string of characters (unless it is wrapped in quotes), but the number 600
in units of pixels
. This is why it can do operations on it just fine, without you having to worry about it. It can do so whether those units are em
or %
or any other valid CSS unit.
Subtract from a value obtained through variable interpolation
The output of ~"@{breakpoint-@{breakpoint}}"
is always a string and so the compiler just appends the number to the string instead of performing the math operation.
One way would be to use a temporary variable like shown below (have added only the part that needs modification) and then perform the arithmetic operation.
.Mq(@breakpoint; @rules; @maxMin: min) {
/* the rest of the mixin */
& when not (@maxMin = min) {
@temp: ~"breakpoint-@{breakpoint}";
@break: (@@temp - 1); /* the braces are mandatory, without which it again appends */
@query: ~"(max-width: @{break})";
@media screen and @query {@rules();};
}
}
/* the selector blocks and mixin calls */
Below are few things that I found while working on the solution which have left me stumped. I'm trying to find the reason and will update the answer when I do find it out.
- The braces play an important role in the
@break
variable. Without it, the output in media query is still a concatenation. However, if the same variable is used outside the media query (in a normal property-value pair likeprop: @break
, it prints the subtracted value). - The below code returns concatenated value (800px - 1)
whereas the below gives a "Operation on invalid type" compiler error.@break: ~"@{breakpoint-@{breakpoint}}" - 1;
prop: @break;
while I can see the reason behind them (first one results in string concatenation whereas second says subtraction can't happen on a string value), I am a bit stumped as to why the behavior is not consistent between the two.@break: ~"@{breakpoint-@{breakpoint}}";
prop: @break - 1;
(You are definitely not a laughing stock. Though I knew the reason for the problem, it took time for me to find a solution.)
Escaping string in less and passing variables
Use string interpolation:
filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr=@{startColor}, endColorstr=@{endColor})";
Variable from string interpolation returns a non unit value
Nested interpolation i.e. ~"@{section-row-padding-size-@{size}}"
is not officially supported in Less. (It works in current versions but may stop to work at any moment eventually).
The correct method to achieve what you want is:
.section-row-padding(@size) {
@var-name: "section-row-padding-size-@{size}";
@padding-size: @@var-name;
padding: (@padding-size * 2);
}
or shorter:
.section-row-padding(@size) {
@padding-size: "section-row-padding-size-@{size}";
padding: (@@padding-size * 2);
}
See "variable references" for @@
meaning.
The problem is caused by the
@padding-size
not interpreted as a px unit but rather as a string.
Exactly. Using ~""
is like saying to the compiler "do not interpreter this value, it's just some string with whatever value I want you to pass through". Thus the type of the value returned by ~"@{section-row-padding-size-@{size}}"
in your example is not a number and it can't be used with arithmetic operations (hence: "Operation on an invalid type").
(A few links for "why ~""
should be avoided whenever possible": 1, 2, 3, 4 etc.).
Get Less variable value from string
(I cannot skip this to not provide an alt. answer since such "namespace emulation via variable name concatenation" is my most favourite bloody wrong Less pattern (unfortunately it is also the most widely spread one :().
Instead of emulating namespaces via using looong global variable names (doh#1 in most of programming languages and paradigms global variables are considered harmful since 1970's... :) and then assembling those variable names via the ugly concatenation syntax (doh#2, ~"@{@{@foo}}-@{bar}-seriously}?"
), one can use normal namespaces with much more clean syntax:
.theme(beach) {
@font-color: #3d3d3d;
// other beach variables
}
.theme(ocean) {
@font-color: #d3d3d3;
// other ocean variables
}
@theme: beach;
.theme(@theme);
body {color: @font-color}
This is just one of possible variations (for more examples see:
- Dynamic Variable Names with Less -> gist
- How to thematize in lesscss
- etc.)
How can I force LESS (css) to recognize a variable?
Try this:
@mediaVersion: 101;
#branding{ background: url("../img/branding.jpg?v@{mediaVersion}"); }
The section "String interpolation" at http://lesscss.org/#-variables shows that this should work.
Slashes (`/`) in CSS values when using Less (e.g. in `font` shorthand)
Just ran into this issue, the escape function (for less.js anyway) is:
e()
Like this
font: @weight @size e('/') @height "Helvetica Neue", Arial, "Liberation Sans", FreeSans, sans-serif;
Related Topics
How to Put The Text of Footer in Center and The Links of Menu in Center and Next to Each Other
How to Capitalize The First Letter of an Input
How to Do Math Within a Less CSS String Interpolation
How to Apply a CSS Stylesheet to All Page Views in My Firefox Browser
How to Draw a Border Around The Text of a Javafx Label
Bundletable.Enableoptimizations True Breaks Jquery-Ui All.CSS
CSS Background to Stretch to Window Bottom
Flex-Box Box-Sizing: Border-Box Not Working
Why Is The User Agent Style Sheet The Last One Style Sheet to Be Applied
Flexbox Does Not Work in Safari, Striked Out in Web Inspector
How to Fix Safari Mix-Blend-Mode: Color-Dodge Bug
CSS Select Second Level Elements
Is There a Cross-Browser Way to Condense Text on a Page
What Is CSS "[Class*=My-Class] .My-Subclass" Doing
My Less Math Operations Aren't Working in My Media Query Definitions