Can you explain the guidelines for overlapping CSS media queries?

When it comes to spacing out media queries accurately to prevent overlap, how should we approach it?

Let's examine the following code as an example:

@media (max-width: 20em) {
    /* styles for narrow viewport */
}

@media (min-width: 20em) and (max-width: 45em) {
    /* styles for slightly wider viewport */
}

@media (min-width: 45em) {
    /* styles for everything else */
}

What happens at exactly 20em and 45em across different browsers that support these queries?

I've noticed that some people use specific pixel values like 799px and then 800px, but what about situations where the screen width is something like 799.5px? Especially on high-resolution displays like retina screens.


I'm particularly interested in understanding the specifications behind this query handling.

Answer №1

What are the guidelines for CSS media query overlap?

Cascade.

@media rules follow the cascade, meaning that when multiple @media rules match simultaneously, browsers should apply styles from all matching rules and resolve any conflicts through cascading.1

What occurs in all supported browsers at exactly 20em and 45em width?

When the viewport is precisely 20em wide, both your first and second media queries will match. Browsers will apply styles from both @media rules, resolving conflicts by giving precedence to the last-declared rule. The same applies when the viewport width is exactly 45em for the second and third media queries.

In your provided example code with actual style rules:

@media (max-width: 20em) {
    .sidebar { display: none; }
}

@media (min-width: 20em) and (max-width: 45em) {
    .sidebar { display: block; float: left; }
}

At exactly 20em wide, both media queries will be true. In this case, display: block overrides display: none, and float: left will be applied to elements with the class .sidebar.

The cascade operates as if the media query conditions did not exist initially:

.sidebar { display: none; }
.sidebar { display: block; float: left; }

To prevent overlap, ensure that your media queries do not intersect.

Remember, both min- and max- prefixes signify "minimum inclusive" and "maximum inclusive," respectively. Thus, (min-width: 20em) and (max-width: 20em) will both match a viewport of exactly 20em in width.

Regarding fractional pixel values such as 799.5px, it's unclear how browsers handle them precisely due to logical pixels in CSS. Safari on iOS appears to round fractional values to ensure they fit within defined ranges like max-width: 799px or min-width: 800px.


1 While not explicitly stated in the Conditional Rules module or the Cascade module (which is set for revision), the standard implies normal cascading behavior, instructing browsers to apply styles from all matching @media rules without special hierarchy.

Answer №2

Following the recommended approach, I attempted the following:

@media screen and (max-width: calc(48em - 1px)) {
    /*mobile styles*/
}
@media screen and (min-width: 48em) {
    /*desktop styles*/
}

Unfortunately, this method proved to be ineffective as it did not work on Chrome either on my Ubuntu desktop or Android phone. This issue is discussed further here: calc() not working within media queries. However, I discovered an alternative solution...

@media screen and (max-width: 47.9999em) {
    /*mobile styles*/
}
@media screen and (min-width: 48em) {
    /*desktop styles*/
}

Success!

Answer №3

calc() can be utilized in order to address this issue

(min-width: 50em and max-width: calc(50em - 1px)
will be displayed correctly stacked), however, due to poor browser support, I do not recommend it.

@media (min-width: 20em) and (max-width: calc(45em - 1px)) {
    /* for slightly wider viewport */
}

Information:

Some have suggested that avoiding the em unit would improve the stacking of your queries.

Answer №4

Recently, I made an interesting discovery while experimenting with device emulation in MS Edge (v118.0.2088.46) within DevTools. When selecting Responsive dimensions and setting a width of 599px, I noticed that the specified media query was not being applied as expected:

@media (max-width: 599px) {
    ...
}

Strangely, adjusting the display width to 598px or slightly modifying the media query to max-width: 599.5px results in the desired outcome. It seems like there may be some sort of internal rounding issue causing this behavior.

I also observed the same issue in Chrome version 118.0.5993.89 and Firefox version 118.0.2.

Answer №5

Starting from March 2023, newer browsers (check out Can I Use) have implemented support for the new range syntax. This allows for more concise expressions of queries. For instance, you can now write width <= 20em instead of max-width: 20em.

What's interesting about this syntax is that it not only supports the <= and >= operators (similar to min-width and max-width comparisons), but also includes < and >. You now have the ability to make a decision on whether or not to include the endpoints of your range!

Take for example your original query:

@media (width < 20em) {
    /* styles for narrow viewport */
}

@media (20em <= width < 45em) {
    /* styles for slightly wider viewport */
}

@media (width >= 45em) {
    /* styles for everything else */
}

This eliminates any uncertainty when dealing with specific viewport widths like exactly 20 em. It clarifies that only the second rule will apply in that scenario. Similarly, at exactly 45 em, only the third rule will take effect.

If desired, you can modify some of the <= comparisons to < and vice versa. This way, when the viewport is exactly 20 em wide, the first rule will be triggered instead of the second. You also have the option to have both rules applied at the breakpoints if needed. The key point here is that you now have control over what happens at precise width points in your design.

Answer №6

If you only have two options, you can utilize the not operator:

@media (max-width: 20em) {
    html { background-color: red; }
}

@media not all and (max-width: 20em) {
    html { background-color: blue; }
}

Please Note: Including all in the query is necessary to use not.

Note: The not operator will negate the entire query regardless of parentheses, see: Inverting a query's meaning

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The CSS module is disappearing before the Framer Motion exit animation finishes when the path changes

Source Code Repository: https://github.com/qcaodigital/cocktail_curations Live Site: I recently deployed my NextJS project to Netlify and everything seems to be working fine, except for one issue. Each page has an exit animation (currently set to change ...

Is Flex still wrapping elements even when set to nowrap?

My goal is to create a layout with 4 blocks, where the first section contains 2 blocks each occupying 50% of the width, followed by 2 other blocks in the next section. I am utilizing the flex property for this layout. I want the flex-container to take up ...

The fixed position seems to be malfunctioning and behaving more like absolute

I have a simple question. I am currently designing a mobile version of a page, and we are trying to keep the "snag it" yellow button fixed at the bottom. However, the 'position: fixed' property is not working as expected; it's behaving like ...

In Bootstrap 5, the anchor tag is causing a shift in the background color of surrounding tags upon being clicked

Why does clicking on an anchor tag temporarily change the background of other tags that weren't clicked? What am I doing wrong? https://i.stack.imgur.com/ZKlUT.png Check out the code below: <nav class="navbar navbar-expand-lg navbar-light bg- ...

Looking for assistance with text alignment?

23 Years Young From: The Boogie Down Bronx Heritage: Puerto Rican Pride Trade: Master Tailor For a demonstration, click on this link ...

Easily showcase a limitless number of items within a 10-column grid using Bootstrap!

This is the code snippet: <div *ngFor="let minute of state.minutes.specificMinutes.selectedMinutes | keyvalue" class="col-sm-1 checkbox-container"> <div class="custom-control custom-checkbox"> <input type="checkbox" (click)="state.m ...

5 horizontal navbar with dropdown menu in Bootstrap

I am currently utilizing bootstrap 5. Is it possible to display my navbar menus horizontally like the image provided? show submenus horizontally as shown in this picture I would also like to implement submenu for other submenus up to 4 levels deep. Any ...

Angular is throwing error TS2322 stating that the type 'string' cannot be assigned to the type '"canvas" while working with ng-particles

My goal is to incorporate particles.js into the home screen component of my project. I have successfully installed "npm install ng-particles" and "npm install tsparticles." However, even after serving and restarting the application, I am unable to resolve ...

Is storing text in data-content and utilizing bootstrap-popover.js compatible?

Is it possible to display HTML content in a popover using ? How reliable is it to store text in data-content? Can we expect it to function properly across all browsers? ...

How can we refine the user information based on the selection of a radio button?

How do I apply a filter to user details when selecting a radio button? Visit Plunker *I need to display only the questions of authenticated users on the list page, so I created a plunker example. If the user is authenticated or an admin, I want to filter ...

The Material UI month picker interface is not displaying correctly

When trying to implement the code snippet below, <MonthPicker/> I am encountering issues with the UI of the month picker both on the website and at times. https://i.stack.imgur.com/EKsYA.png It seems like the month picker is being utilized in a di ...

I aim to arrange three div elements in a single row with varying widths - placing one on the left, another in the center, and the last

I am trying to have three div elements in one row with different widths - one on the left, one in the center and one on the right. The left div should be 160px The center div should be 640px The right div should be 160px My goal is for them to appear se ...

Creating CSS style rules for aligning table column headers in JavaFXML

Is it possible to style columns individually in a tableview? I have been attempting to make some column headers left-aligned and others right-aligned, as shown below: | hdr1 | hdr2 | hdr3 | hdr4 | In my css stylesheet, I experimented with the following ...

Utilizing Ajax to fetch a div element from a web page

Hey there! I have a link set up that loads a page into a specific div ID, which is #ey_4col3. The issue I'm facing is that it loads the entire page along with all its contents, but what I really want to load from that page is just the content within ...

Separate Your Navbar with Bootstrap 4 Separators

I'm facing a challenge in adding separators within a navigation bar between the navigation items. I am unsure how to evenly space out the padding on these separators next to each navigation item. Another issue I encountered is that the separators are ...

Finding an element based on its styling attribute, such as its position on the left or right side

One particular block that caught my eye is the slider element: <div id="sliderDispo" class="slider slider-dispo" data-slider-init="" data-slider-color="#0077b5 #EC6E31 #E40B0B" data-slider-step="33" > <div class="slider__interval" ...

Is there a Unicode character substitution happening?

There are certain mobile browsers that appear to have trouble supporting all unicode characters, such as the down arrow icon like this: span.icon:after { content:"\25be"; } Currently, no symbol is shown. Is there a way for me to identify this i ...

Navigate between pictures using hover in jQuery

I am working on creating a feature where images cycle through individually every 2 seconds, but switch to the right image when its associated link is hovered. So far, I have managed to make the images show up on hover, but I am struggling with getting them ...

Searching for a comprehensive guide to web-related terminology that is widely accepted

Constantly immersing myself in studying the languages I am familiar with and exploring new development concepts and languages is a regular practice for me. When it comes to books, O'Reilly is my go-to choice, but when it comes to online resources, I&a ...

HTML list style with varying images at the same level in a ul tag

I am working on an Application that generates output with li tags. I am trying to find a way to apply different list-style-image for each li tag of the same level within the ul, while keeping the HTML code as simple as possible. Each li with a class of gre ...