How can I isolate adjacent media queries using em? - css

When switching between significantly different appearances for elements, say the menu for mobile and for desktop, I isolate them by having one in a query with a max-width one pixel less than the min-width of the other.
#media screen and (max-width: 767px) {...}
#media screen and (min-width: 768px) {...}
This means I don't have to worry about unexpected behaviour because I forgot to reset an elements ´display´ or ´position´ and if they are different enough it probably keeps the css smaller.
How can I do the same using em?
A difference of 1em is obviously to much and while .0625em is fine if the base is 16px the whole idea of using em is that this isn't necessary the base and will cause an unstyled gap at higher font-sizes.
Defining the max-width: X.999em or something similar doesn't work either as the browser will simply round that up depending on its precision and the font-size.
Since this has to work with IE8 (+ respond.js) calc isn't an option, though I'm not sure if calc can even be used for queries.

I did not knot too if is possible to use calc() in media queries (but sincerely I don't think could be) but eventually.... for IE8 retro-compatibility, there are some js polyfills, like:
Calc-Polyfill
Polycalc
Anyway, I found myself too references to '16px' value. In this Website there is the possibility to convert em in px so... if you declare differences in em between 0.63 and 1.125, you will be inside '1px' interval

Related

Setting CSS media query for overlapping resolutions

I came across a situation in a project were i wanted to write media queries for iPad Air and iPad Mini separately. What i am wondering is how can i target it differently since their resolutions are overlapping. for example
#media only screen and (min-width: 768px) and (max-width: 1024px) { //iPad Mini
.content{
background-color: grey;
}
}
#media only screen and (min-width: 820px) and (max-width: 1180px) { //iPad Air
.content{
background-color: blue;
}
}
What background-color will be applied to the content class for the screen resolution which is between 820px to 1024px since it applies for both the cases? Please correct me if my understanding is wrong. what is the best way to handle such situations? thanks in advance
For screen sizes between 820px and 1024px, blue will be applied as the background color. Since both styles would validly apply to an element with class "content", and have the same specificity, the browser will apply whichever style comes last in the stylesheet. Read more here: https://css-tricks.com/precedence-css-order-css-matters/
It is technically possible to detect what device a user is using to browse your website, but only through exploitation of certain bugs, and likely not easily. You certainly can't write a media query that explicitly targets a specific device.
Even if you could easily, I wouldn't recommend it. In general, you should not design for specific devices - you should have a single, responsive design that neatly adapts to many different screen sizes.
If you're just looking for a good set of breakpoints, a common set of non-overlapping breakpoints are the Bootstrap breakpoints. A possibly better thought-out alternative are David Gilbertson's breakpoints.
Unless you have a good reason not to, you should just stick to using only min-width media queries (if your site is designed mobile-first), or just max-width media queries (if your site is designed desktop-first). This way, styles neatly and predictably overwrite each other as screen sizes get larger (in the first case) or larger (in the second case).

How to calculate CSS zoom factor in dependence on screen width?

Why I am asking this question?
I don't want to create so many media queries for really big screens.
If the screen size is bigger than 1920px, all the existing proportions should remain the same, and the appearance should be simply bigger in dependence on screen width.
What I need is something like that:
// PSEUDO CODE!
#media screen and (min-width: 1921px) {
.content-block {
zoom: calc (100vw divided by X) // <- HERE
}
}
Example:
X = 15
Screen width = 4000px
Zoom-factor = 400 / 15 ~ 266%
X is just any magic number.
Someone might think that if 1900 is 100%, maybe 19.2 might be a better fit, but I've tried out many numbers; 15 fits very well in my current case. If the screen width is, for example, 4000px, I need a zoom of 266%. The choice of the X shall not be confusing here.
The scaling only starts from 1921px according to the set media-query, but that is also a secondary issue.
It is primarily about determining a dynamic zoom factor, which changes depending on the resolution (also on the current window width, therefore 100vw, not 100%), without creating tons of media queries.
Final Notes:
I've already started a bounty once. The given answer is wrong. I don't know why people upvote it. If you click on "run code snipped" and open the result in a new window and resize the window, you will see, it does not work when you resize the window.
In the desired solution, the zoom factor should continuously change while you resize the window.
Last but not least:
No JavaScript, please, CSS solutions only. It is enough if it works in Chrome and Edge of Today.
Something like this could work (you may have to juggle a bit with the numbers to get the intended result):
#media screen and (min-width: 1290px) {
.content-block {
zoom: calc((100% / 15) * 100)
}
}
<div class="content-block">
alalala
</div>
Notes
I used a lower screen breakpoint so I can test it with my display (I don't have a 4k display)
It has one caveat of calculating with the width of the parent, but if you use body for the calculation, it might just work.
expand the snippet so you can see the difference.
Update
However, a better solution would be to set a root em of a given size (which approximates 10 px) and increase this value above a specific screen size using media queries. It's also important to use rem as measurement unit everywhere in your stylesheets (instead of em, px).
Linked question: How to set base size for rem
It is primarily about determining a dynamic zoom factor, which changes depending on the resolution [...] No
JavaScript, please, CSS solutions only.
This in itself would be possible, though one statement of your question limits the solutions tremendously: "I don't want to create so many media queries for really big screens.". Unfortunately, without the usage of lots of media queries this won't be solvable.
Let me elaborate on this bold statement. You can't get the screen width and/or height with CSS only (cf. this). The only possibility you have is to use #media queries - they were invented for exactly this purpose, i.e. your CSS should be displayed in a certain way if width is equal or less than 1200px would be written like that:
#media (max-width: 1200px) {
/* Specific CSS for 0px <= width <= 1200 */
}
If you accepted JavaScript, we obviously would be able to grasp the current width and height via $(window).width(), respectively $(window).height() or even the screen width and height via screen.width and screen.height (click here for an example). But as you specifically mentioned not to include JS, I'll go more in-depth into a CSS solution:
That out of the way, we now know we can't get the screen dimensions with CSS only, hence we're not able to dynamically solve this due to inability of calculating the "magic X factor". What are we able to do then? Well, as mentioned above #media queries were specifically designed for such a use case!
#media is available on nearly all modern browser, see here for the graph:
With #media we could build a logic similar to this:
#media all and (max-width: 2559px), (min-width: 1920px) {
/* specific CSS for this screen size */
}
#media all and (max-width: 3839px), (min-width: 2560px) {
/* specific CSS for this screen size */
}
Obviously, you could custom fit your #media queries in a way so your "dynamic" zoom still looks flawless. In my example I took the sizes for a WQHD and UHD resolution into consideration, hence the first CSS will be execute if it's 1440p, the second one if it's 4k (here is a list of common monitor/TV resolutions).
Obviously, using too many #media queries will be a disadvantage - performance-wise and from a maintainability point of view. I'd love to give you a better solution, but going with the strict rules you have enforced upon this question, it's hard to suggest anything aside the function originally developed to achieve such a goal. If you still want to go with CSS-only, may take a look at this GitHub repo - it helps to keep the #media queries more sorted.
Last but not least, I thought of going into detail regarding the zoom factor, but it seems like you got that under control (judging by your specific examples - in your case, you'd need to calculate your X value for each #media query you decide to implement in the end).
Besides the links mentioned above, I suggest the following for further reading purposes:
A general revision about viewport lengths
Regarding zoom/scale (especially if you decide to go with JS)
Documentation about CSS3 Media Queries, very useful!
Another tutorial about #media
I don't think that the zoom factor can be calculated via CSS in any way.
You can, however, get a similar result using a 3d construct.
In the snippet, a div that has a width of 400px is zoomed to full width adjusting the transform of the body.
(You need to set the snippet to "full page" to see it working.
div {
width: 395px;
background-color: tomato;
border: solid 1px black;
}
body {
transform: perspective(100vw) translateZ(calc(100vw - 400px));
transform-origin: left center;
}
<div>Test</div>
do you have complete control of this website? Here is what I suggest:
For true resolution independence you need to forget about pixels.
Forget about zoom too, that's a non-standard feature.
Go to the base of your DOM and define the font-size with vw, like:
body {font-size:1.2vw;}
Then define all other sizes in em (not rem because that stays constant), ie like:
img {width:20em; height:auto;}
Then you can code exceptions for layouts based on the aspect ratio of the viewport.
/* the only use of px is to isolate the mobile version */
#media screen and (orientation: portrait) and (min-width: 981px) {body {font-size:2vw;}}
#media screen and (orientation: landscape) and (min-width: 981px) {body {font-size:1.2vw;}}
#media screen and (max-width: 981px) {body {font-size:4vw;}}
You can also consider isolating layouts for custom aspect ratios by replacing the portrait/landscape keywords with aspect ratios, as described here:
https://developer.mozilla.org/en-US/docs/Web/CSS/#media/aspect-ratio
You can see this strategy in action on this website I made:
https://bludumpsterrental.com/

Max-Width vs. Min-Width

Most of the tutorials I'm reading on using Media Queries are demonstrating the use of min-width, but I'm rarely seeing people using max-width.
Is this some sort of design trend, or pattern, why people are using min-width over max-width?
For example, I'm designing a site starting from mobile, working up to the desktop. I am using Foundation 4, but using media queries to remove various elements on the page and re-position the source order.
One thing I am facing is a custom navigation for any device whose width is 360px or less. I want them to have a vertical navigation, rather than an inline horizontal. So my idea was to use max-width to target these devices.
Should I be using min-width instead if I am designing mobile first? I.e. all the default styles are for mobile, and thus using min-width to progressively enhance the layout?
2 Part Answer
Part 1: To answer "why people are using min-width over max-width?":
It has to do with design flow. Typically, with min-width patterns, you're designing mobile-first. With max-width patterns, you're design desktop-first.
Going mobile-first with min-width, the default style is the mobile style. Queries after that then target progressively larger screens.
body {
/* default styles here,
targets mobile first */
}
#media screen and (min-width:480px) {
/* style changes when the screen gets larger */
}
#media screen and (min-width:800px) {
/* And even larger */
}
Conversely, using max-width, is desktop-first then adds queries to make styles mobile-friendly
body {
/* default styles here,
targets desktops first */
}
#media screen and (max-width:800px) {
/* style changes when the screen gets smaller */
}
#media screen and (max-width:480px) {
/* And even smaller */
}
Part 2: For your particular custom navigation for any device who's width is 360px or less:
You could include that as a separate max-width query, IF thats the only exception to the rule. OR use that style as your baseline, then change it for wider screens.
If you do an exception (which isn't really following mobile-first design methods), it'd be something like:
body {
/* default styles here,
targets mobile first
ALSO will cover 361 - 479 width */
}
#media screen and (max-width:360px) {
/* style ONLY for screens with 360px or less width */
}
#media screen and (min-width:480px) {
/* style changes when the screen gets larger */
}
etc...
It really depends on how your stylesheet works. For example:
#media screen and (min-width:100px) {
body { font-weight:bold; }
}
#media screen and (min-width:200px) {
body { color:#555; }
}
The above two media queries would make the body font bold if the screen is greater than or equal to 100px, but also make the color #555 if it's greater than or equal to 200px;
Another example:
#media screen and (max-width:100px) {
body { font-weight:bold; }
}
#media screen and (max-width:200px) {
body { color:#555; }
}
Unlike the first example, this makes the body font bold and color #555 only if the screen width is between 0 and 100px. If it's between 0px and 200px it will be color #555.
The beauty of media queries is that you can combine these statements:
#media screen and (min-width:100px) and (max-width:200px) {
body { font-weight:bold; color:#555; }
}
In this example you are only targeting devices with a width between 100px and 200px - nothing more, nothing less.
In short, if you want your styles to leak out of media queries you'd use either min-width or max-width, but if you're wanting to affect a very specific criteria you can just combine the two.
In short, min-width is a mobile 1st approach, max-width is a desktop 1st approach.
Min-width is the minimum width at which a style will START to be applied. (Have to be ordered from smallest to largest to work properly, regular styles first). Put another way: If device width is greater than or equal to..., then apply some specific styles. With min-width, styles START and continue forever as long as min-width is met, and no max-width is specified.
Max-width is the maximum width at which a style will continue to be applied. After that, the style will STOP being applied. (Have to be ordered from largest to smallest to work properly, regular styles first). Put another way: If device width is less than or equal to..., then apply specific styles. Styles STOP as soon as width greater than max-width is hit.
Finally, It depends on how you want to implement. There is no ONE RIGHT solution as some may claim. In my opinion min-width works great when starting from scratch, but max-width often makes more sense to me when retrofitting an existing web site.
What are Mobile-first and Desktop-first approaches?
A mobile-first approach to styling means that styles are applied first to mobile devices. Advanced styles and other overrides for larger screens are then added into the stylesheet via media queries.
This approach uses
min-width
media queries.
Here’s a quick example:
// This applies from 0px to 600px
body {
background: red;
}
// This applies from 600px onwards
#media (min-width: 600px) {
body {
background: green;
}
}
In the example above, will have a red background below 600px. Its background changes to green at 600px and beyond.
On the flipside, a desktop-first approach to styling means that styles are applied first to desktop devices. Advanced styles and overrides for smaller screens are then added into the stylesheet via media queries.
This approach uses >max-width
media queries.
Here’s a quick example:
// This applies from 600px onwards
body {
background: green;
}
// This applies from 0px to 600px
#media (max-width: 600px) {
body {
background: red;
}
}
will have a background colour of green for all widths. If the screen goes below 600px, the background colour becomes red instead.
Because you're developing a website starting with a mobile design and increasing complexity with resolution, I would advise going with min-width because that follows the same work pattern.
Technically, min-width is "mobile first" in the sense that you generally begin developing for mobile and add more complexity as the resolution increases.
However, the term gained popularity more so over its alternative meaning which has generally come to imply more about an increase of focus on mobile efforts and prioritization (mostly fueled by clients or management that don't understand the technical inference). That is likely why you end up seeing a lot of min-width examples online (trendy bloggers writing about trendy topics).
When I work with complex desktop designs, I personally find it easier to write max-width queries to "simplify the equation" so-to-speak. But using max-width queries does not prevent you from focusing on mobile and can still completely be a part of a "mobile first" strategy.
In either case, the most important thing is consistency. Use one and stick to it for that project. A project can become very confusing if it uses both.
As a final note, using less queries when possible is ideal. This can be achieved through good responsive design.
I had a unresponsive website first, designed for desktops. Then added responsiveness by adding max-width media queries.
My site now has layouts for 320px, 480px, 768px, 960px, and 1024px etc. wide devices, and so I have added media queries that look like max-width: 479px, max-width: 767px, max-width: 959px etc. This works fine - the site behaves as it should.
However, I've recently found that the Chrome Developer Tools "Device Mode" has a Media Queries Tool that is really, really useful to me. It allows me to click to display the website at each media query level that Chrome finds on my page. This is a great help to me when designing the responsive layouts.
The Media Queries Tool uses the numbers it finds in the media queries, i.e. 479, 767, 959, 1023 etc. But this means that, for example, if I want to see what how my layout for a 480px-wide device looks, I have to click the max-width 767px level media query, which to me is quite unintuitive.
This has made me rethink my current desktop-first CSS, and I will be rewriting my CSS using a mobile-first approach.
I think the mobile-first CSS using min-width will be much more readable, because you will see a media query for min-width: 480px and know that will be the CSS for a 480px-wide device.
The majority of sites I've been working on are designed for desktop first and in these cases using max-width queries makes sense. Generally if you are starting small screen first use min-width and then build on top with media queries targeting larger resolutions.
You can of course mix both min and max queries to get specific resolutions
Maybe have a look at using min-device-width for the specific issue you're having with the navigation

Change phone/desktop transition width cutoff for responsive Twitter Bootstrap

I'd like to change the "cutoff" width (currently 767px) at which Bootstrap changes from small-desktop mode (i.e. grid elements in a row are still horizontally placed) to phone mode (i.e. grid elements in a row are placed on top of each other and fill the screen width). Specifically, Bootstrap uses queries like #media (min-width: 768px) and (max-width: 979px). It seems that the 767 and 768 are hard-coded into the LESS source code, though. Is there a supported way to do this, or will I just have to make the changes manually and hope it doesn't break anything?
EDIT: Yes, I know that Twitter chose these values for a reason... it just strikes me as odd that seemingly everything else in the framework is modular and customizable.
The LESS value you look for is
#grid-float-breakpoint: 123px;
You have to override the responsive part of Bootstrap. I would not load bootstrap-responsive and load my own ones. Everything is defined in responsive*.less files.

scaling a web layout with the viewport

I am aware of the CSS 3 units vw, vh and vm, which seem to be useful for making elements that have their box sizes and text sizes relative to the browser's viewport size. However, sadly, these are not well-supported with the current major browsers; only Internet Explorer 9+ does.
What other methods can I use to do things like CSS font-size properties that scale with the viewport? I would like to avoid JavaScript and/or jQuery solutions if possible.
Doing a 100% scalable website is possible. As Rev said, you can do this by using percentage values, but it is tricky.
The better option is to utilize #media queries. These allow you to apply CSS rules to a page only under certain conditions. By using media queries to detect the device width and/or the page width, you can apply fine tune control over how your site looks AT different viewport sizes. For instance:
#media screen and (max-device-width: 960px) {
font-size:14px;
}
#media screen and (max-device-width: 480px) {
font-size:13px;
}
Now, the above example is rather trivial and contrived. For a deeper understanding of what you can accomplish with media queries, I recommend you view the W3C spec page. Some of the most powerful are the width, min-device-width, max-device-width, portrait|landscape, and print queries.
As a side note, make sure to include these styles at the bottom of your CSS, so that they dont get overwritten by default styles.

Resources