How to properly use css-values viewport-relative-lengths? - css

As per Is there a way to up-size the font with CSS to fit the screen?, it's possible to use css3-values/#viewport-relative-lengths (dev3, dev), vw, vh, vmin, vmax, to make the document more fluid.
However, coming from the conservative side, I'd like to ensure that my desire to fit the screen on larger displays doesn't do harm on smaller ones.
I know that with <meta name = 'viewport' content = 'width = device-width' /> and the implicit font-size: 1em;, I'm supposed to be guaranteed that the font size in my page will basically be the same as the font size of the interface elements, and no unnecessary scrolling should appear, either.
As per above, is there a way to ensure vw / vh / vmin / vmax to never ever go below the absolute value of the above relative 1em? Perhaps something do with with CSS4 / CSS3 media queries (dpi, width, length etc)?

By definition, a vw unit is supposed to represent 1% (i.e. 1/100th) of the width of the viewport. (Can anyone confirm if it's roughly the same for the paged media?)
As such, if the viewport width is 50em, then 1vw will equal 0.5em, or, in other words, 1em will equal 2vw.
As such, it would indeed be a good idea to only ever use the vw unit within a media query; it seems like the easiest and most practical visual design and the math would be to target a minimum of 50em width (and also height) as above, and then 2vw (or, if we target minimum height with our media query, too, 2vmin) would guarantee to mean at least 1em, or, in other words, it would guarantee that the magnification will always be at least 100%.
For example, as for OpenBSD ports category listing, the following could be used to magnify the list of the categories (if the window itself is oversized and has sufficient height, too) without affecting the rest of the page nor diminishing the experience on the smaller-sized windows. Here, we use vmin to combat against too much magnification in landscape view (which would result in up/down scrolling), but you have to be careful to also specify a min-height of at least 50em, too (otherwise, we'll be getting below 100% magnification with 2vmin, if the height were to fall below 50em).
#media (min-width: 50em) and (min-height: 50em) {
/* guarantees at least 1em in all viewports */
ul {font-size: 2vmin; -webkit-columns: 4;}
}
(Note that the above appears to detach the ul elements from being zoomable by the user when the rules apply (at least when tested in my Google Chrome), so, overall, the question for best practice still stands.)
Or, for a small business-card-style front page, which only lists your name/address/contact details:
/* automatically magnify business-card-style page in large viewports */
/* please don't use this unless you yourself posses a large monitor! */
#media (min-width: 50em) and (min-height: 64em) {
/* start with 100% at 50em, we'll have 150% magnification at 75em */
html {font-size: 2vmin;}
}
#media (min-width: 75em) and (min-height: 96em) {
/* start with 225% magnification at 75em (75 / 100 * 3 = 2.25) */
html {font-size: 3vmin;}
}
As I was writing this, I also realised that in order to avoid so much magnification as to cause the introduction of the scrolling, it seems like we must absolutely specify both the min-width and min-height of something like 50em, and then also use only the vmin as our unit. Otherwise, a really widescreen window will be magnified way too much with mere 2vw, such that excessive and unnecessary scrolling is very likely to get introduced.

Related

How to work with percentage rates instead of px rates in responsive design?

So I've applied for a front end job few months ago and got interviewed and they've given me a test task. One of the requirements of this task is that they want the website to be infinitely variable scalable like this one.
To quote the task description it says:
If you scale down the browser window, everything fits perfectly because everything scales in the same ratio. For that you have to work with percentage rates instead of px rates.
Now, my problem is I am a PX guy, I mean I build all of my projects using px and not that confident on using different unit such as em, vw, rem etc. Well I've use other unit like vh but I don't use it often.
So what's the best way to learn or any roadmap that'll help me to migrate from px to percentage. Should I just use tools like px to em?
Practice does make perfect
The short answer is... Start practicing using percentage-based units as that's how you'll learn the little catches. This is a good career move anyway as the idea of matching pixels to a design was crushed long ago with HiDPI screens, mobile devices, etc all rendering pixels differently.
Getting Started
Practically, you need a place to start and that means learning a few new CSS tools.
First
Use rem as a substitute for pixels.
Unlike an em that's relative to its parent font-size, a Rem is relative to the font-size of the root element (usually body) which means its GLOBAL. You can use rems everwhere (font-size, margin, padding, position, etc) and they're ALL based on the root size.
So let's say the root font size is 16px (typical browser default). That means 1rem = 16px. Now a 16px base isn't overly useful when you're doing math in your head. Jonathan Snook wrote about why this works years ago but the basic formula is set the base font size to 62.5% (of 16px) this means that 1rem = 10px and it's much easier to do the math.
Here's what that looks like in code:
body {
font-size: 62.5%;
}
h1 {
font-size: 2.4rem;
/* 2.4rem = 24px */
}
p {
font-size: 1.2rem;
/* 1.2rem = 12px */
}
.padding-left {
padding-left: 2rem;
/* 2rem = 20px */
}
You get the idea...
Fun tip: once you like the layout you can change the body font-size and make everything bigger or smaller. This is useful for things like a small screen where you want the fonts to be a bit larger
Next
CSS Calc() Is your friend. It's designed to help you do math operations on mixed unit values. For example, the browser can then do this type of math: 33.33% - 200px.
.element {
width: calc(33.33% - 20px);
/* maybe you need responsive columns with 10 px of padding on either side */
}
Finally
Start doing all your layout in percents. For example instead of a 3 column layout set to 300px wide (not responsive). You should make them 100/3 or 33.3333333% wide. Percents like this are always based on the parent so 100% = parent's width (regardless of the parent's units).
As a side note, I rarely need to use vh/vw, not because they aren't useful but in general, elements overflow their window in very predictable ways and percents are easier to wrap your head around.
vw and vh are going to be your best bet if it needs to be a percentage of the screen. rem and em are still relative to a starting point (i.e. body { font-size: 16px; } and scaled from there. vw and vh do have some issues on smaller device screens though, but it looks like your demo website has this issue. You can fix this with media queries, but it doesn't look like your example did, it "infinitely" scales as you mentioned.

Responsive Font-Sizes: Which values are appropriate?

I'm currently occupied with responsive font-sizes.
How units like vh, vw, vmin are meant is clear to me.
But I'm not able to accomplish something convincingly with them.
The are either to large on large screen-size and then to small on small screens. Or vice-versa.
Are there any general rules which values are appropriate?
For example: h1 should be 2vw, h2 should be 1.5vw, p should be 1vw and so on ...
Should I use vw or vh and why?
Hackape is correct in their comment that this is not a code question. But to answer the actual question of "Which values are appropriate" in a code sense then the answer is all of them.
You can use vw to make your fonts grow/shrink with the width of the viewport. Alternatively you can use vh to make the grow/shrink in relation with the height.
As for your point about being too large or too small, you have at least two options.
Media Queries
Using media queries you can control font sizes for specific sizes the same way you can control any other part of the website in a responsive design.
p {
font-size: 2vw;
}
#media (min-width: 600px) {
p {
font-size: 1vw;
}
}
Don't use that example for design advice but you can see how you can easily control the values appropriately based on your choices.
CSS Locks
A good alternative to this is a technique called CSS Locks. This is not actually a part of CSS, instead it is a formula for CSS Calc that is known to work very well for giving a minimum and maximum to font sizes.
There are a few good articles about CSS Locks, one of them is Florens Verschelde's The math of CSS Locks.
Here's an example from CSS-Tricks' Fluid Typography:
p {
font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
}
As you can see, no media queries are used. And if you want to use vw or vh you can.

Inconsistent vh unit behaviour

I have a pseudo element that appears on hover with:
height: 0.4vh;
The height doesn't change, only the width does. For some reason, however, under certain conditions the heights of different pseudo elements differ (both of the darker lines here have height: 0.4vh):
I put up this fiddle to demonstrate, but realise that it depends on the viewport height whether this weirdness happens:
https://jsfiddle.net/vuw693La/
I am having this issue on Chromium and Firefox. Am I doing something wrong or is there no way to be "pixel perfect" with vh units?
There's some imprecision in browser renderings, especially when percentages or viewport units come into play. In this case, I'd consider whether it's actually worth it to make the height of those lines tied to the viewport. It seems limited to within a few pixels of variance for most screen sizes; maybe either set one size for it, or set static sizes at several breakpoints to gradually scale it up.
.icon_piece::after { height: 1px; }
// tweak breakpoints to whatever works best for your design
#media (min-height: 600px) {
icon_piece::after { height: 2px; }
}
#media (min-height: 900px) {
icon_piece::after { height: 3px; }
}
Some browsers have inconsistencies when using viewport units, specially smaller than 1vw or 1vh.
The way I solved this problem is by assigning larger units (multiplying them by 4 for example) and then using transform: scale(0.25); to get the element back to the desired size.
This is not a straightforward solution as you probably will have to rearrange your code to make it work but I couldn't find any other workaround.

Media Query to Target ONLY Mobile

I want to make a media query to target just my phone. What breakpoint(s) would I use?
For instance, my body max-width is 800px wide with 2px margins. When the window is less than 800px (mobile?) i want the margins on it to be 0px (this works on my browser). Turns out that my phones screen is hi-res and therefore the width of the display never goes below 800px!
Is this because of pixel ratios?
What do I do?
The meta-view-port tag changes how websites are displayed on your phone, or other small screens that may want to 'adjust' a website for you.
Some screens, for instance - an iphone 5 - with no meta-view-port tag, will size the website to fit your screen / but like a little version of your website zoomed out. https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag
A combination of a view-port tag, and a media-query in your styles would allow you to change your style rules depending on the screen-size. It's kinda best just to make the breaks where things get ugly and not based on the screen sizes of "Today" that will change next month.
I would suggest building from the smallest screen first and moving up as you go with styles like this:
html {
height: 100%;
background: blue;
}
#media (min-width: 400px) {
html {
background: red;
}
}
#media (min-width: 850px) {
html {
background: green;
}
}
etc.
https://jsfiddle.net/5qhmrym5/
If you already have your site built.. and you really want to target the smaller screens, you can use max-width instead of min-width - but I've found that it takes more time and energy to override styles on the way down - then it does on the way up because styles get more complex for larger screens.
#media (max-width: 850px) {
/* styles */
}
If what you want to change is margin value when viewed on mobile you should design your display for use on any screen above the mobile size, 800px wide for you, then create a media query, similar to the ones in the link commented by #Hynes, which changes just margins to 0px.
You are correct in assuming your device is 800px wide due to ratios, but it also has to do with resolution, which are similar topics here. If you imagine a sports jumbo screen, a pixel is nearly an led in size, vs a 1080px display laptop, where the pixels are nearly unobservable. Ratios and resolutions are the reasons displays are tricky to make, and why values such as em's and percentages have come to be, to bypass the differences in display. This is also a large reason of why media queries are so useful
html {
box-sizing: border-box;}
*,*:before,*:after {box-sizing: inherit;}
Try using box-sizing: border-box on your css and also percentages, this is the way I like it, but surely you will find plenty of information about it, just google it.
Found the solution: https://stackoverflow.com/a/18500871/5906166
You need to include this in your header:
<meta name="viewport" content="width=device-width, initial-scale=1">
Explanation:
Fortunately, you can specify a viewport meta tag in the <head> section
of your document in order to control the width and scaling of the
browser's viewport. If this tag has a content value of
width=device-width, the screen's width will match the device
independent pixels and will ensure that all the different devices
should scale and behave consistently.

Increase font-size on higher resolutions

I have a website 960px in width with little content, when viewed on resolutions over 1400 > there is too much white space. I want to increase font-size on some elements so it fills the empty height on higher resolutions. How can I achieve this without making it responsive?
Thanks.
Media queries are a great option, but you may also want to try using EM or %. Both of these are relative values depending on screen size or PPI. Generally you can start from 0.8em for your <p> tag and go from there.
You can also try to fiddle around with line-heights but I am unsure of how exactly you could differentiate them without media queries.
EXAMPLE
p {
font-size: 0.8em;
line-height:1.2;
}

Resources