Using Less, can I use the current value in a #media section? - css

I have the following Less code:
#appbar-padding: 10px;
.container {
padding-bottom: #appbar-padding + 10;
}
#media (min-width: 750px) {
.container {
padding-bottom: #appbar-padding + 20;
}
}
Is it possible to take the current value of the padding-bottom in the #media part? So I could do something like:
#media (min-width: 750px) {
.container {
padding-bottom: #this + 10;
}
}
This way, if I change the "normal" .container rules to, say, #appbar-padding + 20, the rules for screens bigger than 750px wide will, in effect, have #appbar-padding + 30 instead of + 20.

As suggested by Harry, you have to pass through an intermediate variable. An example of code could be:
#appbar-padding: 10px;
#default-padding:#appbar-padding + 10;
.container {
padding-bottom: #default-padding;
}
#media (min-width: 750px) {
.container {
padding-bottom: #default-padding + 20;
}
}
The idea is to pre-define "default" (what you call "normal") value for padding, that is calculated starting by #appbar-padding and then apply it to .container.
In Media query, this "default" value is what you change again. In this way, you can simulate your desired behaviour.
NOTE: you must declare #default-padding:#appbar-padding + 10; outside .container class definition because of scope.

Related

Calculate in media queries with SCSS

Is it possible to calculate in media queries when using SCSS and a variable?
I would like to assign a value to a breakpoint variable and in some cases calculate + 1 directly in the media query SCSS file like this:
$bp-xl: 1024px;
#media (min-width: $bp-xl + 1) { ... } /* MIN-WIDTH = 1025px */
So my new min-width would be 1025px.
you can use calc(#{$bp-xl} + 1px);. calc does the calcuation, the #{} is string interpolation, which lets you insert a variable into calc
Yes, It's Possible!
Have a look for Demo! https://codepen.io/navdeepsingh/pen/qpejKo
h1 {
font-size: 12px;
background: green;
color: white;
}
$bp-xl: 1024px;
#media (min-width: $bp-xl + 6) {
h1 {
font-size: 50px;
background: pink;
color: black;
}
} /* MIN-WIDTH = 1030px */
<h1>HELLO</h1>

Pass Less.js variable into media query [duplicate]

This question already has answers here:
Using LESS variables in media queries
(1 answer)
My LESS math operations aren't working in my media query definitions
(1 answer)
Closed 7 years ago.
I want to pass this variable into a media query:
#browser-main-and-sidebar: #main-width + #main-spacer + #sidebar-width + #outer-padding*2;
where:
#outer-padding: 20px;
#main-width: 600px;
#main-spacer: 10px;
#sidebar-width: 290px;
When I write this out:
#media (min-width: #browser-main-and-sidebar) {
max-width: #browser-main-and-sidebar;
}
The CSS generated is:
#media (min-width: 600px + 10px + 290px + 20px*2) {
.Jobzi__core {
max-width:1240px;
background: black
}
}
Is there a way to force the compuation of the variable into a single pixel value?
As seven-phases-max stated in the comments above, strict math is implied within #media queries.
LESS - Strict Math
With strict math on, only maths that is inside un-necessary parenthesis will be processed.
Therefore you need to wrap the variables that you want to be evaluated within parenthesis:
#browser-main-and-sidebar: (#main-width + #main-spacer + #sidebar-width + #outer-padding * 2);
..or:
#media (min-width: (#browser-main-and-sidebar)) {
max-width: #browser-main-and-sidebar;
}
Both of which will compile to the desired result of:
#media (min-width: 940px) {
max-width: 940px;
}
#outer-padding: 20px;
#main-width: 600px;
#main-spacer: 10px;
#sidebar-width: 290px;
#browser-main-and-sidebar: #main-width + #main-spacer + #sidebar-width + #outer-padding * 2;
#media (min-width: (#browser-main-and-sidebar)) {
max-width: #browser-main-and-sidebar;
}

Generate styles using LESS recursive function and media queries

I am trying to generate some relative to screen height and decided to try to use LESS to generate something like that, even if a bit heavy just as a test:
#baseHeight: 1px;
.setRelativeHeight(#screenHeight, #minHeightDiff, #maxHeightDiff) when(#screenHeight < 2400) {
#media (min-height: #baseHeight * #screenHeight) {
min-height: #baseHeight * (#screenHeight - #minHeightDiff);
max-height: #baseHeight * (#screenHeight - #maxHeightDiff);
}
.setRelativeHeight(#screenHeight + 20, #minHeightDiff, #maxHeightDiff);
}
That seems to work, most of it, but this is part of what it generates when calling it:
#media not all {
#ConversationMessages .messages {
max-height: 2100px;
min-height: 2000px;
}
}
#media not all {
#ConversationMessages .messages {
max-height: 2120px;
min-height: 2020px;
}
}
#media not all {
#ConversationMessages .messages {
max-height: 2140px;
min-height: 2040px;
}
}
#media not all {
#ConversationMessages .messages {
max-height: 2160px;
min-height: 2060px;
}
}
So the styles are being set properly but the media condition is lost :( Does anyone know why? :)
Thanks!!
Update
Fixed adding parenthesis to the media condition (see comment below).
Arithmetic operations inside #media queries should always be in parens regardless of --strict-math option. I.e. should be #media (min-height: (#baseHeight * #screenHeight)).

Can you create custom breakpoints with LESS mixins?

Most of the time, I use LESS variables with preset breakpoints for media queries like this:
#s-max : ~"screen and (max-width: 40em)";
#m-max : ~"screen and (max-width: 50em)";
#l-max : ~"screen and (max-width: 60em)";
USAGE
.some-class {
color: red;
#media #s-max {
color: blue;
}
}
But sometimes, I would like to be able to refer to an arbitrary breakpoint in my .less stylesheet without having to set a new preset value in my separate mixin file.
You can do this in SASS. The mixin looks like this:
#mixin bp-min($canvas) {
#media only screen and (min-width:$canvas) {#content;}
}
USAGE
#include bp-min(750px) {
//responsive styling for min-width of 750px
}
In LESS, I'm imagining the equivalent mixin would look something like this:
.bp-min(#min) {
#media only screen and (min-width:#min)...
}
The only problem is, the lack of the {#content} argument in LESS, which grabs the rest of the styling inputted by the developer. I love SASS, but I can't use it at work.
Does anyone know of a LESS-based solution to this problem?
It is now similar to SASS
As of 1.7.0 (2014-02-27) you can now use #rules in place of the sassy #content.
For example:
.breakpoint-small(#rules) {
#media screen and (min-width: 40em) { #rules(); }
}
ul {
width: 100%;
.breakpoint-small({
width: 50%;
});
}
outputs, as expected:
ul {
width: 100%;
#media screen and (min-width: 40em) {
width: 50%;
}
}
The differences being:
function takes #rules as an argument
additional parenthesis when invoking the function
'.' syntax as opposed to '#include'
This can be combined with an additional argument to provide syntax equivalent to a nice bit of sass:
.breakpoint(#size, #rules) {
#media screen and (min-width: #size) { #rules(); }
}
#large: 60em;
ul {
.breakpoint(#large, {
width: 50%;
});
}
edit: To be honest I prefer a way more simple approach in less:
#break-large: ~"screen and (min-width: 60em)";
ul {
#media #break-large {
width: 50%;
}
}
Source: I too use sass at home and less at work
Using Pattern Matching
I believe this achieves what you want:
LESS
/* generic caller */
.bp-min(#min) {
#media only screen and (min-width:#min) {
.bp-min(#min, set);
}
}
/* define them */
.bp-min(750px, set) {
test: (#min - 300px);
}
.bp-min(400px, set) {
test: (#min - 100px);
}
/* call them */
.bp-min(750px);
.bp-min(400px);
Output CSS
#media only screen and (min-width: 750px) {
test: 450px;
}
#media only screen and (min-width: 400px) {
test: 300px;
}
By defining a set pattern mixin for the various sizes, and then using that pattern within the generic .bp-min(#min) mixin, I believe we have the same abstraction in LESS that you have in SCSS, with slightly more code because I believe SCSS defines and calls in one #include statement, whereas here we need two.
(In addition to the prev. answer) Or something like this:
.bp-min(#canvas) {
#media only screen and
(min-width: #canvas) {.content}
}
// usage:
& { .bp-min(900px); .content() {
color: red;
}}
& { .bp-min(600px); .content() {
color: blue;
}}
// more usage examples:
.class-green {
.bp-min(450px); .content() {
color: green;
}}
& { .bp-min(300px); .content() {
.class-yellow {
color: yellow;
}
.class-aqua {
color: aqua;
}
}}
Replace .content with .- if you prefer shorter stuff.
In my case I needed my variables to reference other variables, so some of these solutions did not work. Here is what I went with.
#bp-xs: ~"screen and (max-width:"#screen-xs-max~")";
#bp-sm: ~"screen and (max-width:"#screen-sm-max~")";
#bp-md: ~"screen and (max-width:"#screen-md-max~")";
#bp-lg: ~"screen and (max-width:"#screen-lg-max~")";
and then use them like so
#media #bp-sm {
...
}

LESS: Subtract from variable

Using LESS, how can I subtract values with "px" at the end of the variable. I have the following variable:
#bpMobile: 600px
What I want to do is subtract this by 1px
#media only screen and (max-width: #bpMobile - 1px ) {
}
How can I achieve this with LESS?
Sorry for answering this late, but I had this very problem and it seems LESS is picky about the spacing. You also need () around your calculation.
This will not work:
#media screen and (max-width: (#widthSmall-2)) { }
However, this will (notice the space between the variable and the digit):
#media screen and (max-width: (#widthSmall - 2)) { }
You can always use the calc function for this.
Syntax:
calc(expression)
Eg:
abc {
width:calc(100%-20px)
}
Here are the list of browser that supports this function
EDIT 1:
you can use it in the following two ways:
LESS Input:
#bpMobile: 600px;
max-width: calc(~'#{bpMobile} - 1px');
CSS Output:
max-width: calc(600px - 1px);
2nd Way:
Less Input:
#bpMobile: 600px;
max-width: calc(#bpMobile - 1px);
CSS Output :
max-width: calc(599px);
With the first option,the calc arguments are escaped in order to prevent them from being evaluated on compilation.The values will remain totally static until it's evaluated by the client.
With the second option, the calc value will be evaluated on compilation. And it would be the same as
max-width: #bpMobile - 1px;
which will result in
max-width: 599px;
The fix from freejosh does not work for me on lesscss 1.7.0.
What does the trick is simply adding paranthesis around every variable or calculation inside a media-query:
#media only screen and (max-width: (#bpMobile - 1px) ) { ... }
or
#other: #bpMobile - 1px;
#media only screen and (max-width: (#other) ) { ... }
The problem isn't the math function, it's that you're trying to use it in a media query. The docs say that you need to make the whole query one variable:
#bpMobile: 600px;
#bpMobile1: #bpMobile - 1px;
#singleQuery: ~"only screen and (max-width: #{bpMobile1})";
#media #singleQuery {
}
————————————————————————————————
In my case .
.loop(#i) when (#i > 0) {
#index : #i + 1;
.abc_#{i}{
z-index : #index;
}
.loop(#i -1);
}
.loop(8);
will give output:
.abc_8{
z-index : 8 + 1;
}
————————————————————————————————
Another case :
.loop(#i) when (#i > 0) {
#index : pow(#i,1) + 1;
.abc_#{i}{
z-index : #index;
}
.loop(#i -1);
}
.loop(8);
will give output:
.abc_8{
z-index : 9;
}

Resources