Extra parentheses cause simple media query to fail - css

I just came across a weird thing and was wondering if this is expected behaviour or indeed some sort of bug.
My intention is to write the following code but I narrowed down the issue (see below).
#media only screen
and (
(-webkit-min-device-pixel-ratio: 1.2), /* or */
(min-resolution: 120dpi)
) { ... }
This code works:
#media only screen
and (-webkit-min-device-pixel-ratio: 1.2) { ... }
adding extra outside parentheses (round brackets), this fails:
#media only screen
and ( (-webkit-min-device-pixel-ratio: 1.2) ) { ... }
The target platform is latest Chrome on Android 5.1, but I'm open to hear comments on other platforms too.

It depends on what behavior you need to approach. Whether you need and or or for those rules
If you want to apply both of rules for media query, you need to use and logical operator
#media only screen and (-webkit-min-device-pixel-ratio: 1.2)
and (min-resolution: 120dpi)
{ ... }
If you want to apply any one of the rules for media query, you need to use comma :
#media only screen and (-webkit-min-device-pixel-ratio: 1.2),
only screen and (min-resolution: 120dpi)
{ ... }

Related

Why does Bootstrap use a 0.02px difference between screen size thresholds in its media queries?

// Extra small devices (portrait phones, less than 576px)
#media (max-width: 575.98px) { ... }
// Small devices (landscape phones, 576px and up)
#media (min-width: 576px) and (max-width: 767.98px) { ... }
// Medium devices (tablets, 768px and up)
#media (min-width: 768px) and (max-width: 991.98px) { ... }
// Large devices (desktops, 992px and up)
#media (min-width: 992px) and (max-width: 1199.98px) { ... }
// Extra large devices (large desktops, 1200px and up)
#media (min-width: 1200px) { ... }
Code sample source: https://getbootstrap.com/docs/4.1/layout/overview/
What's the reason for using .98px? Cross-browser compatibility?
Related: What are the rules for CSS media query overlap?
There isn't a good way to make two px-based #media rules mutually exclusive with no gap without repeating the same media query twice and using the not keyword — which isn't very readable much less DRY — and the < and > syntax new to Media Queries 4 isn't widely supported yet. As you've seen in my answer to the linked question, a viewport that is (in this example) exactly 576px wide will match both max-width: 576px and min-width: 576px simultaneously, which can cause issues (some cascading some not) as properties from both rules will be applied. Most authors therefore choose to have min- and max- constraints with a difference of 1 pixel, or less if they're worried about high-resolution displays with non-integer pixel densities that don't scale every CSS pixel to full device pixels (e.g. 1.5).
Indeed, cross-browser compatibility is the reason: according to Bootstrap's source, 0.02px is used "rather than 0.01px to work around a current rounding bug in Safari. See https://bugs.webkit.org/show_bug.cgi?id=178261" (that, predictably, as of July 2018 still hasn't been fixed). Starting from line 31 of _breakpoints.scss:
// Maximum breakpoint width. Null for the largest (last) breakpoint.
// The maximum value is calculated as the minimum of the next one less 0.02px
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
// See https://bugs.webkit.org/show_bug.cgi?id=178261
//
// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 767.98px
#function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
$next: breakpoint-next($name, $breakpoints);
#return if($next, breakpoint-min($next, $breakpoints) - .02px, null);
}

Two media queries contradictorily went true. which will win?

which media condition will win in the given code below?
.img {
background-image: url(small.jpg);
}
#media (-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
.img {
background-image: url(medium.jpg);
}
}
#media (min-width: 800px) {
.img {
background-image: url(large.jpg);
}
}
There arises two possibilities.
Suppose the screen is greater than 800px and also has device-pixel-ratio equals to 2, then both the media queries resolves to true.
which image will be retrieved?
and is there any chance that both will get requested at the runtime
(though only one will shown up overriding the anther)
impacting(degrading) the performance by causing loading-time
overhead?
Well, going by the rules of cascading it should be the last one. but I'm not sure if media queries have any kind of specificity like how an ID trumps a class.
This was marked duplicate of What are the rules for CSS media query overlap? but there is another aspect of this question(mentioned in point-2) which is not addressed in that marked-duplicate.

Media Queries: Target all high resolutions displays

I am working on a future proof fluid website and dont agree with the following:
#media
only screen and (-webkit-min-device-pixel-ratio: 2) ,
only screen and ( min--moz-device-pixel-ratio: 2) ,
only screen and ( -o-min-device-pixel-ratio: 2/1) ,
only screen and ( min-device-pixel-ratio: 2) ,
only screen and ( min-resolution: 192dpi) ,
only screen and ( min-resolution: 2dppx) {
}
The world is not only retina or devices with 1, 1.5 or 2 pixel ratio. We will keep on having more numbers in the future. My question is: how do I target all those resolutions and future resolutions?
My problem is I have SVG versions of my PNG (PNG to support older browsers and devices with pixel ratio 1) for high resolution displays with I want to come into effect when the user has "any" high resolution display like the retina. So in order to spare all the tons of media queries and have it all future proof I prefer to write it once only. Like a master media query for all high resolution screens, be it mac retina, iphone, dell, HP, etc, nexus phone, etc.
Also why only min-resolution: 192dpi or 2dppx? I mean what about pixel density 1.5 144dpi ? isnt it better to set the minimum to lets say 100dpi (standard is 96) and everything above the normal will use my SVG. 100dpi, 101, 102......144dpi......192.......300dpi........900dpi.......1000 dpi and so on.
/* 1.25 dpr */
#media
(-webkit-min-device-pixel-ratio: 1.25),
(min-resolution: 120dpi){
/* Retina-specific stuff here */
}
/* 1.3 dpr */
#media
(-webkit-min-device-pixel-ratio: 1.3),
(min-resolution: 124.8dpi){
/* Retina-specific stuff here */
}
/* 1.5 dpr */
#media
(-webkit-min-device-pixel-ratio: 1.5),
(min-resolution: 144dpi){
/* Retina-specific stuff here */
}
/* 2 dpr */
#media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi){
/* Retina-specific stuff here */
}

Chrome is not picking up CSS media queries when using optimisations in bundles

As I have mentioned in the title - chrome is not picking up the media queries. For example:
#media only screen and (min-width: 481px) and (max-width: 784px)
#media (min-width: 481px) and (max-width: 784px)
It works if I leave only one width property:
#media only screen and (min-width: 481px)
All other browsers picks this up ok. Did anyone of you came to this issue as well and can help me to get on track?
Edit
I'm using the latest version of chrome (Version 32.0.1700.76 m)
There is a bug in chrome where it won't read media queries without the correct spacing. If you look at your bundled source code (when minified) you will probably notice that #media (min-width: 481px) and (max-width: 784px) has been transformed to #media (min-width: 481px)and (max-width: 784px) (notice the missing space after the bracket).
This article explains the problem well and also a fix which is basically to create a class that implements IBundleTransform and implement Process at which point you can check for this problem and fix it:
public class CssMinifyMQ : IBundleTransform {
public void Process(BundleContext context, BundleResponse response) {
response.ContentType = "text/css";
response.Content = Regex.Replace(response.Content, "(\\) and ( )?\\()", ") and (");
}
}
bundles.Add(
new Bundle("~/CSS/Base", new CssMinifyMQ()).Include("~/Content/Base/*.css")
);
HTH!

Media Queries: Target retina macbook pro only

I'm using media queries for my site and it works perfectly from web to mobile.
Now I want to use some styles exclusively Apples Retina MBP's (NOT iPad, iPhone, etc.).
But I can't get it to work, when I change the CSS, it changes only on all devices.
Does anyone know a bulletproof media query only for the Macbook Pros which he tested?
I use this Media queries:
#media
only screen and (-webkit-min-device-pixel-ratio: 2) and (min-device-width: 1025px),
only screen and ( min--moz-device-pixel-ratio: 2) and (min-device-width: 1025px),
only screen and ( -o-min-device-pixel-ratio: 2/1) and (min-device-width: 1025px),
only screen and ( min-device-pixel-ratio: 2) and (min-device-width: 1025px),
only screen and ( min-resolution: 192dpi) and (min-device-width: 1025px),
only screen and ( min-resolution: 2dppx) and (min-device-width: 1025px) {
/* MacBook-Retina-specific stuff here */
}
Source: http://css-tricks.com/snippets/css/retina-display-media-query/
Media queries don't detect user agents/devices; they detect features (such as resolution & orientation). Try using javascript and applying a class to the body, and applying styles from there.
var retina = (window.retina || window.devicePixelRatio > 1);
if (retina) {
$('body').addClass('retina'); // for example
}
Then in your css
body.retina {
// styles
}
body.retina #element {
// styles
}
Source: http://hjzhao.blogspot.co.uk/2012/07/detect-retina-display-using-javascript.html
I would try with
#media screen and (min-height: (yourtargetdevicepixelsheight)px) and (min-width: (yourtargetdevicepixelswidth)px) {
you styles here
}
As it is Apples Retina MBP's I dont think many devices can have both conditions, you could also lock it adding
and (max-height: (yourtargetdevicepixelsheight+1)px ) and the same with 'width'
hope it helps

Resources