Search code examples
cssmedia-queries

Proper cascading media queries? / Odd media query behaviour on screen resize / refresh


I have inherited a large site, which is a mixture of being static, adaptive and responsive. The responsive media queries have a load of overlapping areas

@media only screen and (min-width: 300px) { /random code }

and further down the page;

@media only screen and (max-width: 400px) { /more random code }

so at 350px, both should trigger?

So when resizing a browser window, I got some weird behaviour in that the queries would trigger, but then refreshing the page at that size, a media query higher in the cascading sheet would trigger instead. But on resize, the proper cascaded media queries would fire.

I am working to make the site responsive from desktop down, so I redid all the media queries as (max-width) such like;

@media only screen and (max-width: 600px) { /random code }
@media only screen and (max-width: 500px) { /random code }
@media only screen and (max-width: 400px) { /random code }

Yet I am still getting strange behaviour in other parts of the site using this method, even though on other sites it works fine. (I.e. refreshing at 550px and '@media only screen and (max-width: 400px)' is being fired.)

It got me wondering if I was using them the right way. A number of sites have contradicting answers on how media-queries are properly used. I'm starting to get the feeling it should be something like;

@media only screen and (min-width: 501px and max-width: 600px) { /random code }
@media only screen and (min-width: 401px and max-width: 500px) { /random code }
@media only screen and (max-width: 400px) { /random code }

But doesn't this fly in the face of the cascading aspect of CSS?


Solution

  • Ok, I'm going to agree with @Michael 's comment and expand on it after fixing my issue and after a little more research. I'll adjust the title too in-case someone else stumbles across this issue.

    Firstly my issue of the media queries being overridden - was my error. I wasn't using SCSS or grunt on this project so I missed an extra closing brace that confused chrome and chrome inspector.

    #div {
       default code
    }
    
    @media only screen and (max-width:450px) {**}**
        #div {
            media query code;
        }
    }
    

    So when the page loaded at 430px, the erroneous media query code overwrote the default code. Then when I refreshed / resized the page, chrome freaked out. Inspector had the media query listed (so I didn't think there was an error) but the media query code was crossed out as if it had been overridden by another query. So use a validator.

    As for the correct use of media queries, I agree with @Michael in that I feel using either

    (min-width: Mpx)
    

    (when designing mobile up) or

    (max-width: Dpx)
    

    (when designing desktop down) exclusively is the better DRY method, over defining ranges

    (min-width: Xpx and max-width: Ypx)
    

    since changing the range of one media query will mean changing the range of at least one other. Also I feel such ranges as the other answers given here are adaptive (even though the definition of adaptive / responsive seems to blur all over the net).

    I've noticed that some sites which use these ranges look nice on those devices, but testing on different resolutions (and who can guess future ranges?!) these sites just look cropped or broken. But perhaps they were just implemented incorrectly...

    With a responsive site (perhaps elastic?), defining media queries by eye where content is about to break, seems not only intuitive, but future-proof for any future devices. Content is always scaled to the screen, rather in blocks to predetermined (mostly apple) device widths.

    So I've kept using solely

    @media only screen and (max-width: 600px) { /random code }
    @media only screen and (max-width: 500px) { /random code }
    @media only screen and (max-width: 400px) { /random code }
    

    Because its DRY (and would be more so with SCSS) and the default code aimed at desktop first is much easier to convert to IE8 than starting mobile first.

    I hope this helps someone in the future.