My LESS math operations aren't working in my media query definitions
Just like the CSS logic for the calc()
method, equations within media queries (which are already encapsulated by a set of parentheses) need to be encapsulated by an extra set of parentheses. This won't work:
(min-width: 500px + 1) {CSS goes here}
But this will:
(min-width: (500px + 1px)) {CSS goes here}
Using LESS variables in media queries
Due to Math Settings
LESS by default expects math operations to be in parenthesis (strict-math=on
). So your variable needs those around the values to calculate correctly, like so:
@layout-max-width: (@num-cols * @item-width + @margins);
Then your original code will output as you expect.
Pass Less.js variable into media query
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
Arithmetic operations inside @media
queries should always be in parens regardless of --strict-math
option. I.e. should be @media (min-height: (@baseHeight * @screenHeight))
.
JavaScript - Event listener with window.matchMedia not triggering
Using addListener
instead of addEventListener
fixed the problem.
Why doesn't min() (or max()) work with unitless 0?
You need to add a unit to 0
otherwise it's confusing for the browser to handle the comparison between a uniteless value (a <number>
) and a value with unit (a <length>
) and the top
property accept a <length>
not a <number>
top: max(0px, 120vh - 271px)
To understand this, you need to follow the specification:
The
min()
ormax()
functions contain one or more comma-separated calculations, and represent the smallest (most negative) or largest (most positive) of them, respectively.
Then for calculations:
A
calc()
function contains a single calculation which is a sequence of values interspersed with operators, and possibly grouped by parentheses (matching the<calc-sum>
grammar),
So the content of min()
/max()
is treated like the one of calc()
then from the type checking
A math function can be many possible types, such as
<length>
,<number>
, etc., depending on the calculations it contains, as defined below. It can be used anywhere a value of that type is allowed.
and
Note: Altho there are a few properties in which a bare
<number>
becomes a<length>
at used-value time (specifically, line-height and tab-size),<number>
s never become "length-like" incalc()
. They always stay as<number>
s.
You may get surprised but using top:0
is valid while top:min(0)
or top:max(0)
is not. To make them valid you need to add the unit.
But you can use opacity: min(0)
for example since opacity accept a number as argument.
Worth to note that the same also apply to clamp()
since it's equivalent to max(MIN, min(VAL, MAX))
Related: Why doesn't css-calc() work when using 0 inside the equation?
How to work with percentage rates instead of px rates in responsive design?
Practice does make perfect
The short answer is... Start practicing using percentage-based units as that's how you'll learn the little catches. This is a good career move anyway as the idea of matching pixels to a design was crushed long ago with HiDPI screens, mobile devices, etc all rendering pixels differently.
Getting Started
Practically, you need a place to start and that means learning a few new CSS tools.
First
Use rem
as a substitute for pixels.
Unlike an em
that's relative to its parent font-size, a Rem is relative to the font-size of the root element (usually body
) which means its GLOBAL. You can use rems everwhere (font-size, margin, padding, position, etc) and they're ALL based on the root size.
So let's say the root font size is 16px (typical browser default). That means 1rem = 16px
. Now a 16px base isn't overly useful when you're doing math in your head. Jonathan Snook wrote about why this works years ago but the basic formula is set the base font size to 62.5% (of 16px) this means that 1rem = 10px
and it's much easier to do the math.
Here's what that looks like in code:
body {
font-size: 62.5%;
}
h1 {
font-size: 2.4rem;
/* 2.4rem = 24px */
}
p {
font-size: 1.2rem;
/* 1.2rem = 12px */
}
.padding-left {
padding-left: 2rem;
/* 2rem = 20px */
}
You get the idea...
Fun tip: once you like the layout you can change the body font-size and make everything bigger or smaller. This is useful for things like a small screen where you want the fonts to be a bit larger
Next
CSS Calc()
Is your friend. It's designed to help you do math operations on mixed unit values. For example, the browser can then do this type of math: 33.33% - 200px.
.element {
width: calc(33.33% - 20px);
/* maybe you need responsive columns with 10 px of padding on either side */
}
Finally
Start doing all your layout in percents. For example instead of a 3 column layout set to 300px wide (not responsive). You should make them 100/3 or 33.3333333%
wide. Percents like this are always based on the parent so 100% = parent's width
(regardless of the parent's units).
As a side note, I rarely need to use vh/vw
, not because they aren't useful but in general, elements overflow their window in very predictable ways and percents are easier to wrap your head around.
Related Topics
How to Create an Infinite Background Pattern Animation Using Linear-Gradient
How to See All Edited Styles in Firefox Developer Tools
CSS Div Center Multi-Line Text Vertically and Horizontally with a Background Image
How to Write One CSS Rule for Several Prefixed Selectors
How to Make Sidebar with Same Height as The Content Div
CSS - Style Svg Fill with Class Name
Custom Classname Semantic UI React
Ie Conditional Comments with SASS and Bourbon
CSS: Remove Padding Within Select Element
Margin Collapse for Adjacent Siblings
What Tool How to Use to Test The: Contains() CSS3 Pseudo-Class in a Browser
How to Display Flexbox Items in Two Rows Instead of One
CSS Grid Nested in a Wrapper-Div or a Body Element
Rails 3 - Referencing a CSS Class to Form Elements in an Object Dot Style
How to Create a Row of Justified Elements with Fluid Spacing Using CSS