Responsive Font-Sizes: Which values are appropriate? - css

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.

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.

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.

Why did Bootstrap 4 choose rem and em instead px?

I would like know why Bootstrap chose to use rem and em instead of px for Bootstrap 4.
We can see an example in the variables.scss file within the project:
$font-size-h1: 2.5rem !default;
$font-size-h2: 2rem !default;
$font-size-h3: 1.75rem !default;
$mark-padding: .2em !default;
I couldn't find any explanation by the developers on the web about this. Have they explained why they made this decision anywhere?
REMs are useful almost anywhere size is explicitly set.
With rem, all font sizes are relative to the root element (aka, the
html tag). The reason for this is to make it easier to scale up or down for devices. You could technically change the html tag to a smaller or larger size to scale all font sizes equally – which is a super nice feature.
... [T]he main thing to take-away is everything is dynamic and
relative to the root HTML tag.
For example, change the html css font-size to a different number ...
and watch how the entire grid adjusts and scales.
Source: Scotch.io
It is worth mentioning that Bootstrap 4 kept breakpoints in px and not em. From the docs:
While Bootstrap uses ems or rems for defining most sizes, pxs are used for grid breakpoints and container widths. This is because the viewport width is in pixels and does not change with the font size.
I switched to using rems instead of px a while back, I can tell ya it was the best choice.
Rems are 100% scalable, I base all my sizing on what looks good on a laptops and below, then at 1600px media query or greater, adjust the html font size and viola!, the entire site "scales up" 100% proportionally.
I'm starting to incorporated vw now too for section paddings and fonts that need to go big like that found in hero sections, combine this with calc for example calc(3rem + 2vw) and you've got a seriously scalable website with minimal media queries.
When using rems, you need to reset your html font size to 16px.
html {
font-size: 62.5%;
}
now, 1rem = 10px
so sizing everything is super easy to convert.
30px is now 3rem, 25px is now 2.5rem, 15px is now 1.5rem and so on.
Then on larger screens, change the html to say font-size: 70%, and everything will beautifully scale up.
Be sure to use px for media queries like: #media only screen and (min-width: 1680px)
But 'max-width' can be either px or rems, just depends on the design.
I set my wraps now to 90vw, this prevents anything from touching the screen edge and is and 100% scalable.
.wrap {
margin-left: auto;
margin-right: auto;
width: 90vw;
max-width: 145rem; /* or use px depending on the design */
}
You can use % too, but with WP Gutenberg out and their full width sections using vw I can get everything to line up to a perfect grid.
Hope this helps.
The other answers are missing one main point here. It's correct that with rem you can change the font size on the root(usually the html element) to change all website's text's font size. In this sense rem gives flexibility to web designers to change whole websites font size. But this can be achieved with the new css variables as well. E.g.
:root{--my-font: 16px}
div {font-size: calc(var(--my-font)*2)}
There's a second and the more important reason for the use of rem as following:
Second reason: users can just ctrl + to increase the size if they want to, yeah? Yes, they can. But!, there's another scenario that we need to consider. Users can change the default font size of their browser through the browser settings, e.g. in chrome go to chrome://settings/appearance and you can set the root font size for all websites. What this does is all website which have their font sizes in em or rem will get affected but the ones with px font sizes won't be affected. This is another main reason for bootstrap to switch from px to rem units.
Change you browser default font and run the following example to see it yourself:
.one {
font-size: 24px;
}
.two {
font-size: 1.5em;
}
.three {
font-size: 1.5rem;
}
<div class="one">I will stay the same, no matter what default browser font settings are</div></br>
<div class="two">I will change in size if you change your browser's default font size.</div></br>
<div class="three">I will change in size as well just like div.two</div>
Refrences:
https://www.24a11y.com/2019/pixels-vs-relative-units-in-css-why-its-still-a-big-deal/?ref=heydesigner

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

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.

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