0

I am trying to set up several media queries to set the width of a wrapper div.

I'm finding that the media query is not honoured.

Here is an example of 4 breakpoints with different widths for the outlined div.

If I narrow the screen to 1000px wide, the media query rule states that the div should be 960px wide yet I find it honours instead the largest media query and sets the width to 1388px.

https://codepen.io/asos-francesca/pen/ZEGXjyG

@media only screen and (max-width: 1024px) {
  .wrapper {
    width: 960px;
  }
}

@media only screen and (max-width: 1280px) {
  .wrapper {
    width: 1140px;
  }
}

@media only screen and (max-width: 1400px) {
  .wrapper {
    width: 1300px;
  }
}

@media only screen and (min-width: 1440px) {
  .wrapper {
    width: 1388px;
  }
}

Am I misunderstanding how media queries should work?

connexo
  • 53,704
  • 14
  • 91
  • 128
user1486133
  • 1,309
  • 3
  • 19
  • 37

3 Answers3

1

Think about media queries like "Do I include this" checks. To turn it into pseudo code:

If the screen is less than 1025px {
  .wrapper {
    width: 960px;
  }
}
If the screen is less than 1281px {
  .wrapper {
    width: 1140px;
  }
}
If the screen is less than 1401px {
  .wrapper {
    width: 1300px;
  }
}
If the screen is more than 1439px {
  .wrapper {
    width: 1388px;
  }
}

So if the first statement is true, the others will also be true, leading to the CSS:

.wrapper {
  width: 960px;
}
.wrapper {
  width: 1140px;
}
.wrapper {
  width: 1300px;
}
.wrapper {
  width: 1388px;
}

And as CSS cascades, each of these selectors will overwrite the previous value. The simplest way to fix this us to order the media queries in order of priority.

connexo
  • 53,704
  • 14
  • 91
  • 128
DBS
  • 9,110
  • 4
  • 35
  • 53
  • Ah thanks, that does make sense! So if I were to take a mobile-first approach (though I'm only working on a stylesheet from tablet upwards here so let's say "tablet-first" would you suggest instead converting it to min-width of 1px above what I'm after? – user1486133 Mar 05 '20 at 17:05
  • Just adding a tip : if you have any CSS related problem of _Why is my property applying instead of this one_, you could use the [Browser Developer Tools](https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_and_edit_CSS) :) – Oddrigue Mar 05 '20 at 17:08
  • @user1486133 If you want to set specific boundries connexo's answer provides a nice solution where you set both the min and max sizes to target with your query. – DBS Mar 05 '20 at 17:09
  • This is partly correct. `max-width` says **less then or equal to**. The max-width does not refer to the screen but to the view (useble area) of the browser. Another thing is the gap for views below 1024px, for example if I have a browser and Word document side-by-side, then the view of the browser is less then 960px resulting in a horizontal scrollbar – bron Mar 06 '20 at 13:42
0

In a way, yes. Let's assume your viewport is 1000px as you stated.

The problem

Your browser sees the first matching media query:

@media only screen and (max-width: 1024px) {
  .wrapper {
    width: 960px;
  }
}

This media query matches, so this is what the browser was able to determine at this point of parsing. Of course the parser needs to respect all CSS, so it goes on:

@media only screen and (max-width: 1280px) {
  .wrapper {
    width: 1140px;
  }
}

A screen that is 1000px also satisfies max-width: 1280px, the browser - so far - applies this instead of the previous media query. It then continues to parse and finds ...

@media only screen and (max-width: 1400px) {
  .wrapper {
    width: 1300px;
  }
}

This one also matches!

You get the idea?

How to solve it

To fix it, either order the media queries properly and logically (basically reverse the max-width-based media queries), or be more specific in your media query condition (which is what I would do):

@media only screen and (max-width: 1024px) {
  .wrapper {
    width: 960px;
  }
}

@media only screen and (min-width: 1025px) and (max-width: 1280px) {
  .wrapper {
    width: 1140px;
  }
}

@media only screen and (min-width: 1281px) and (max-width: 1439px) {
  .wrapper {
    width: 1300px;
  }
}

@media only screen and (min-width: 1440px) {
  .wrapper {
    width: 1388px;
  }
}
connexo
  • 53,704
  • 14
  • 91
  • 128
-1

Another way is to begin with 100% width and then set a max-width on the wrapper on each @media. In this example the @media width is top down (desktop first approach)

.wrapper {
  width: 100%;
  max-width: 1388px;
}
@media only screen and (max-width: 1400px) {
  .wrapper {
    max-width: 1300px;
  }
}
@media only screen and (max-width: 1280px) {
  .wrapper {
    max-width: 1140px;
  }
}
@media only screen and (max-width: 1024px) {
  .wrapper {
    max-width: 960px;
  }
}
bron
  • 1,457
  • 1
  • 9
  • 18
  • This has already been suggested in my answer. *To fix it, either order the media queries properly and logically (basically reverse the max-width-based media queries).* – connexo Mar 05 '20 at 17:26
  • In neither of the answers there is a default `width:100%` and using `max-width` for the wrapper in the breakpoints. In my opinion this is a better approch for breakpoints in responsive websites. Please explain the downvote? – bron Mar 06 '20 at 00:09