Evaluating Media queries in a Range Context

Media queries are used to apply CSS styles depending on a device’s type (such as print vs. screen) or other characteristics such as screen resolution or browser viewport width.

//apply style when the document is viewed on a screen in print preview mode
@media print {
  body {
    font-size: 10pt;
  }
}
//apply style to all screens
@media screen {
  body {
    font-size: 13px;
  }
}

For responsive web designs, we use media queries to apply styles based on the viewport width mainly using min-width and max-width.

First, let’s understand the properties max-width and min-width.

max-width: It targets the devices from width 0px to the maximum width assigned. If min-width is specified it takes the min-width as the initial value instead of 0px.

min-width: It takes the initial value that is assigned to it and targets all the devices until the next max-width is provided.

Here is an example of style using min-width and max-width.

//Apply styles for devices with viewport width between 480px and 768px

@media (min-width: 480px) and (max-width: 768px) {
  article {
    padding: 2rem 4rem;
  }
}

Media queries using range context

CSS Media Queries Level 4 specification introduced a new syntax to write such queries using mathematical comparison operators( <, >, =, <=, >= ).

The above style can be written with mathematical operators as below:

//Apply styles for devices with viewport width between `480px` and `768px`

@media (480px <= width <= 768px) {
  article {
    padding: 2rem 4rem;
  }
}

This new syntax also works with a single value.

//Old syntax
@media (min-width: 480px) {
  article {
    padding: 2rem 4rem;
  }
}

//New syntax
@media (width >= 480px) {
  article {
    padding: 2rem 4rem;
  }
}

The code looks much cleaner, right? We don’t have to process the min-width and max-width properties to understand the styling.

Some media features with a “range” type are said to be false in the negative range. Did not get it? Don’t worry, we will explain it in a simple way.

Let’s first keep in mind that using negative values in media queries is valid and must be parsed.

When we query, a media feature is equal to(=), less than(<>), or less or equal than(<=) any negative value, it must evaluate as false.

Let’s take an example mentioned in the Media Queries Level 4 specification.

@media not (width <= -100px) {
  body { background: green; }
}

The width of any device is never less than -100px, so it will evaluate as false. Next, we negate the feature using not. So for all devices, the background will be green.

Now, let’s check another scenario.

When we query, the media feature is greater( > ), or greater or equal( >= ) than a negative value it evaluates to true if the relationship is true.

@media (height > -100px) {
  body { background: blue; }
}

The height of any device will always be greater than a negative value, hence the code will evaluate to true. All the devices will have the background color blue.

Why should we prefer the new media query range syntax over using min-width or max-width?

Suppose, we define different styles based on a breakpoint at 320px in the viewport width using min-width and max-width:

@media (max-width: 320px) { /* styles for viewports <= 320px */ }
@media (min-width: 320px) { /* styles for viewports >= 320px */ }

In this case, when the device’s width is 320px, both conditions are matched. This is not what we want. We want either of the style to apply instead of both to be applied at the same time.

To fix this issue we can make the below changes -

@media (max-width: 320px) { /* styles for viewports <= 320px */ }
@media (min-width: 321px) { /* styles for viewports >= 321px */ }

This fix ensures that the two styles don’t apply simultaneously when the viewport width is 320px.

However, there is still one issue. When the width is between 320px and 321px, none of the styles will apply.

One approach is to change the min-width to 320.01px.

@media (max-width: 320px) { /* styles for viewports <= 320px */ }
@media (min-width: 320.01px) { /* styles for viewports >= 320.01px */ }

Isn’t it an ugly way?

Yes! But do we have any other way of doing this?

Yup, the new range syntax provides a clean and neat solution.

@media (width <= 320px) { /* styles for viewports <= 320px */ }
@media (width > 320px) { /* styles for viewports > 320px */ }

Browser support

The new range context syntax in Media Queries Level 4 specification is not widely supported in all browsers. New versions of Chrome, Firefox, Edge, and Opera have added support for the new syntax. Checkout CanIUse to know more about the supported browsers.

Need help on your Ruby on Rails or React project?

Join Our Newsletter