My Less Math Operations Aren't Working in My Media Query Definitions

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() or max() 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" in calc(). 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



Leave a reply



Submit