3

Im working on a mobile first site. The media queries are set with ems like so:

html {
    font-size: 62.5%;
}
body {
    font-size: 16px;
    font-size: 1.6rem;
}

@media (min-width: 320em) {
}
@media (min-width: 600em) {
}
@media (min-width: 770em) {
}

I now need to add a max-width media query just below the same breakpoint as my middle media query, so that any screen size is either one or the other.

If I was working with px this would be easy:

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

Can the same be done with ems? Just to reiterate, I need it so any screen size will be in either the min or max media query. I cant have any 'no mans land' in between.

As its possible to have decimal places on ems I think the following wont work. A screen could be 599.5ems wide as so be in between the 2 media queries.

@media (max-width: 599em) {
}
@media (min-width: 600em) {
}
Evanss
  • 23,390
  • 94
  • 282
  • 505
  • 3
    You should use px for screen widths as screens are in px and are divided by dpi. –  Jul 23 '15 at 11:18
  • The project has been going for too long now for me to easily change this. Is there no other solution? – Evanss Jul 23 '15 at 11:21
  • What's with the font size multiplication at the top? You know that these factors will let you end up with the same font size as you started out with, right? _If you're lucky._ So why do it at all? – Mr Lister Jul 23 '15 at 12:44

4 Answers4

3

I've built a few sites with both min and max width media queries, and for me they've been painfully difficult to maintain and didn't actually add any value.

I like to use min-width queries for mobile-first sites, because it makes sense to me to think about my design from my smallest screen width first and then slowly add or change features as the width increases. This has the added bonus of eliminating the "no man's land" issue. See example: (thanks @IMI for calculating the pixel widths)

When you build a site like this, you end up specifying everything that changes from the previous query in each subsequent query, but behavior is also much more predictable as your screen will either fall into one category or the other, and whichever one it falls in, you know exactly what properties are being applied.

html {
    font-size: 62.5%;
}
body {
    font-size: 16px;
    font-size: 1.6rem;
 color:black;
}

@media (min-width: 20em) { /* = 320px */
 body {color:red;}
}
@media (min-width: 30em) { /* = 480px */
 body {color:green;} 
}
@media (min-width: 37.5em) { /* = 600px */
 body {color:pink;}
}
@media (min-width: 48.125em) { /* = 770px */
 body {color:cyan;}
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p> This is some random text.</p>
</body>
</html>
Bmd
  • 1,308
  • 8
  • 15
2

Yes, you can use decimals in your em based media queries.

The em values of the media queries will be based on the Browser's "initial" font-size value. This is typically 16px. So you are usually safe calculating your em based media queries by dividing the pixel value by 16.

Example: to get the em equivalent of @media (min-width: 600px) you would divide 600px by 16 which would result in 37.5 and a media query of @media (min-width: 37.5em)

No Man's Land: If you have to mix min-width and max-width media queries it is best to use a max-width media query that equals the min-width of your next media query as stated in @maioman's answer and that should get rid of the "no man's land" gap problem. That way, a device with a max of 600px will use all your styles up to and including the max-width:37.5em styles while devices with have a higher resolution will use the following relevant styles including the min-width:37.5em.

Snippet Example of em based media queries with decimals:

html {
    font-size: 62.5%;
}
body {
    font-size: 16px;
    font-size: 1.6rem;
 color:black;
}

@media (min-width: 20em) { /* = 320px */
 body {color:red;} /* You wont see this color since the max-width media query is overrides it */
}
@media (max-width: 37.4375em) { /* = 599px */
 body {color:green;} /* Be careful where you place the max-width media query. It will override the smaller min-width if placed after. */
}
@media (max-width: 37.5em) { /* = 600px */
 body {color:green;} /* As stated in @maioman's answer, using a max-width that equals the min-width of your next media query should get rid of the "no man's land" problem. */
}
@media (min-width: 37.5em) { /* = 600px */
 body {color:pink;}
}
@media (min-width: 48.125em) { /* = 770px */
 body {color:cyan;}
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p> This is some random text.</p>
</body>
</html>
IMI
  • 2,461
  • 1
  • 14
  • 20
1

since min-width will override max-width if you do something like this you should be safe:

@media screen and (max-width: 600em) {
}
@media screen and (min-width: 600em) {
}

div {
    width:5em;
    height:5em;
}
@media screen and (max-width: 12em) {
    div {
        background:green
    }
}
@media screen and (min-width: 12em) {
    div {
        background:red
    }
}
<div>test</div>

fiddle

maioman
  • 18,154
  • 4
  • 36
  • 42
  • An override cant be relied upon as the different media queries could have different levels of specificity for the different styles. – Evanss Jul 28 '15 at 14:40
  • I don't know if I get what you're saying but overriding the property is the way media-queries work – maioman Jul 28 '15 at 14:57
  • If one media query was (max-width: 599px) and the other was (min-width: 600px) then I would know that one of them will always be used, and also that they won't conflict with each other. Can this be achieved using ems? – Evanss Jul 28 '15 at 15:35
  • I can't think of a 'conflicting' media-queries/property situation, could you make a practical example ? – maioman 4 hours ago – maioman Jul 28 '15 at 20:55
  • @maioman, if you want all of your `

    ` tags to be left-aligned by default, hidden within a particular div on small screens `@media(max-width:12em){#EmptyDiv p {display:none;}}`, and center-aligned on mid-sized screens `@media(min-width:12em){p {text-align:center;}}`, now you have an issue where thanks to the specificity of the declaration on the max-width query, your `#EmptyDiv p` text is hidden when your screen is 12em (when your mid-sized screen layout should be taking effect with visible text).

    – Bmd Jul 28 '15 at 20:56
  • @BrianD - Your example doesn't seem like an issue at all. Adding `#EmptyDiv p {display:block;}` to the `@media(min-width:12em)` media query would fix this hypothetical problem. Example: http://jsfiddle.net/pk9tfzLw/4/. – IMI Jul 29 '15 at 03:56
  • @BrianD you're example doesn't look conflicting, more probably what is meant here as 'conflicts' are the result of unorganized media-queries – maioman Jul 29 '15 at 08:47
  • @jdln if IMI's solution don't work out , you could also think on using JS for a more extensive control – maioman Jul 29 '15 at 08:51
1

The “em” is a scalable unit. An em is equal to the current font-size, for instance, if the font-size of the document is 12px, 1em is equal to 12px. Ems are scalable in nature, so 2em would equal 24px, .5em would equal 6px, etc.

The size can be calculated from pixels to em using this formula: pixels/12(current font-size)=em

Check out http://www.w3schools.com/css/css_font.asp

In media queries “rem” as well as “em” don’t refer to the root element (html) but to the browser defaults directly which can only be changed using the browser settings for base font size. This means that even if you specify a font size of 30px on your html element, media queries will still use "user agent's (browser's) initial font-size" as “em” / “rem” based for the media queries unless you also change your default font size in the browser settings.

I will use(for the good of math):

"user agent's initial font-size" = 10px;

So let say you have:

@media (max-width: 59em) {
}

@media (min-width: 60em) {
}

When the browser compute the em that will be equal to:

@media (max-width: 590px) { // 59 * 10(supposed font-size)
}

@media (min-width: 600px) { // 60 * 10(supposed font-size)
}

Here you have a range of 10px where the screen could between the 2 media queries.

Probably you would say, I do a little math and solve the problem but to do math in css there is calc

like this:

@media (max-width: calc(60em - 1px);) { // 60 * 10 = 600px - 1px = 599px
}

@media (min-width: 60em) {  // 60 * 10 = 600px 
}

But unfortunately calc() not working within media queries.

But 1px = 0.1em 1 / 10(supposed font-size)

So you have to do the math a priori:

@media (max-width: calc(59.9em);) { // 60em - 0.1em(1px) = 59.9 * 10 = 599px
}

@media (min-width: 60em) {  // 60 * 10 = 600px 
}

So the only that you have to do is change the "10" to the "user agent's (browser's) initial font-size" and do the math a priori.

I hope this help you.

Community
  • 1
  • 1
Yandy_Viera
  • 4,320
  • 4
  • 21
  • 42
  • Your math is based on a false assumption. The em value used to specify a max/min-width media query is based on the user agent's (browser's) initial font-size and not from your css declared styles. – IMI Jul 28 '15 at 23:50
  • @IMI I used `html{font-size: 10px}` like I said "(for the good of math)" and just to illustrate. I know that that “rem” as well as “em” in media queries don’t refer to the root element (html) but to the browser defaults directly which can only be changed using the browser settings for base font size. This means that even if you specify a font size of 30px on your html element, media queries will still use "user agent's (browser's) initial font-size" as “em” / “rem” based for the media queries unless you also change your default font size in the browser settings. – Yandy_Viera Jul 29 '15 at 01:02
  • So the only that you have to do is change the "10" to the "user agent's (browser's) initial font-size" and do the math a priori. – Yandy_Viera Jul 29 '15 at 01:03
  • Your example of `@media (min-width: 600px) { // 60 * 10(supposed font-size)}` is misleading and likely to cause confusion to people who are not that familiar with this topic. As I stated in my answer, most modern browsers default to approximately 16px. Therefore, to calculate the em value you would divide the pixel value by 16. So, while your overall em description is accurate for use in css declarations, it is not accurate when discussing media query units. – IMI Jul 29 '15 at 01:17
  • @IMI I don't think that my example is misleading but for the sake of conversation and a better understand of my answer I edited it, even I added my comments to make it more clear, anyway thanks for the suggestion. – Yandy_Viera Jul 29 '15 at 01:56