How can I gracefully degrade CSS viewport units? - css

CSS viewport units (vw, vh, vmin, vmax) are great, and I want to start using them for fonts -- but I noticed here that they aren't that widely supported. I tried to google any best practices for graceful degradation in unsupported browsers, but couldn't find anything useful. Are there any better ways beyond doing something like:
h1 {
font-size: 120%; /* for unsupported browsers */
font-size: 5.3vmin; /* for supported browsers */
}
Thanks in advance!

Native usage
You'll at least want to provide a fallback:
h1 {
font-size: 36px; /* Some tweener fallback that doesn't look awful */
font-size: 5.4vw;
}
Also tells about mimicing the functionality with FitText.js.
For more information, read Chris Coyier's "Viewport Sized Typography" http://css-tricks.com/viewport-sized-typography/

You cannot gracefully degrade the viewport units in CSS simply because there is nothing conceptually even remotely similar in older versions of CSS.
For example, setting font size to 120% does not address the issue at all: it simply sets the font size 1.2 times the parent element’s font size, quite independently of viewport dimensions.
It is, however, possible to approximate the effects of viewport units using client-side JavaScript so that you get the viewport properties and then set the font-size property based on them. See e.g. answers to the question Is there any cross-browser javascript for making vh and vw units work.

As per How to properly use css-values viewport-relative-lengths?, I don't think it's correct to use viewport units outside of restricting them with #media queries for minimum height and width of the viewport, and even then, I think it should only be used when you know that the page they'll be applying to is very small (e.g. a business-card style page), and would otherwise leave the whole viewport screen empty handed.
In other words, what exactly are you looking for when you say font-size: 5.3vmin?
What if I cascade multiple windows one by one, only leaving enough room in each viewport as to see three lines of normal text? The text at 5.3vmin will be so small at to be unintelligible!
Likewise, if I have a huge monitor (say, Seiki 39" # 3840x2160, which, I must point out, is quite affordable at below 400 USD), and you use font-size: 5.3vmin for all your headers on a page with a lengthy article, then you're stripping my ability and comfort to fully enjoy all the extra lines of text that my monitor can support, instead having 5 headers occupy more than a quarter of the screen, which instead could have been filled by a hundred of extra lines of text.

Related

Rem-Based Layouts, Zooming on chrome is inconsistent, PX vs REM

I've been wracking my brain over this one, google searches don't really have much in the way of help or even documentation of this problem but it's greatly affecting my current conversion to a mobile-friendly design.
Everywhere I go, everyone's touting using rem-based layouts as the new gold standard, and on the surface the virtues of this approach seem ideal (full accesibility support for both reference pixel based scaling and font-size scaling to support many DPIs and many screen sizes / settings).
However I've run into a rather large snag, I'm finding that Chrome (and possibly all webkit browsers but I don't have a mac atm to test) don't seem to scale the same as the rest.
With the initial setup like this:
html { font-size: 62.5%; }
body { font-size: 1.6rem; }
We should be able to set up all our measurements using 1/10th the pixel size in rems:
.my-element { height: 15rem; } /* 150px */
I've created a simple example that illustrates my problem here: https://jsfiddle.net/gLkpz88q/2/embedded/result/
When you use Chrome and you scale this way out, notice how the layout stops scaling but the content continues.
Compare this to Firefox, IE11, Edge and you don't see this behavior at all, they all scale uniformly and continually.
Here's (Top-Left: Chrome, Top-Right: IE11, Bottom-Left: Edge, Bottom-Right: FireFox) side-by-side:
As you can see this has some terrible implications for layouts if the rem unit scales differently than everything else.
I'm not certain how to proceed with this scenario as it seems like WebKit/Chrome have decided to handle scaling completely differently and this calls in to question all the scaling scenarios going forward.
There's a number of articles advocating just using pixels as the CSS Reference Pixel takes care of mobile scaling rather well:
Just Use Pixels
R.I.P. Rem, Viva CSS Reference Pixel!
However these tend to ignore the font-scaling issue, citing it as an unlikely situation.
I did a quick look around at man big mobile friendly/friendlyish sites I could think of from large & successful companies and it seems most of them just use pixels for all their layout needs. (Google, Facebook, Wordpress, Twitter, Bootstrap 3, [and to some extent Bootstrap 4], MDN, and WebPlatform)
Is Chrome the new Standards-Busting IE? Or am I doing something horribly wrong? I'm tempted to just use pixels at this point for consistency.
I'm going to start my answer by addressing your closing statement first, purely because it caught my eye (besides the humongous bounty).
"Is Chrome the new Standards-Busting IE? Or am I doing something horribly wrong? I'm tempted to just use pixels at this point for consistency."
Yes and no. I have more problems with things not working in WebKit browsers than I do in any other mainstream browser engine, but after investigating the individual issues, I generally find that it's because WebKit tends to stick to the rules provided by W3C more rigidly than others.
Most other browser engines seem to be very lenient with developers, and I love them for this, but we can't necessarily crucify WebKit for following the rules.
To extend the above statements into the rest of your question, I skimmed through W3C document regarding relative font lengths. Under the heading for rem units you will notice the first line stating:
Equal to the computed value of ‘font-size’ on the root element.
Unfortunately, font-size in itself is relatively open to interpretation by your browser engine.
Cyrix's answer is correct in that Chrome will adjust your font size based on a minimum font-size that it has built in to the engine. To solve your problem easily, you could use the text-size-adjust or the newer font-size-adjust rule on your container element to prevent this:
* { /* Replacing "*" with ".my-element" would probably be better for the rest of your site*/
-webkit-text-size-adjust: none;
-webkit-font-size-adjust: none;
}
The problem however is that older versions of Chrome don't accept font-size-adjust, and newer version only accept font-size-adjust and only when experimental features are enabled.
In closing, to answer the rest of your questions, rem and em is a wonderful unit of measurement if you are working with actual text content etc. Think in the lines of:
If you want your<h1>'s to always be about 25% bigger than your body text h1 { font-size: 1.25rem; }
If the height of your header bar must always be 3 times the height of the line of text inside it .header { height: 3em; }
If however you are working with a container type block that needs to fit a specified content block on the inside, it's always better to work with something more stable. Keep in mind, stability does not mean unresponsive.
Take this for example:
.my-element {
width: 95%;
margin: auto;
max-width: 600px;
}
This will float your element nicely in the middle of the page, whilst keeping the element at a size that fits the content inside it, and if the screen size decreases to a point smaller than your .my-element height, it will adjust accordingly.
In short.
Yes, Chrome breaks things on a scale that makes IE jealous, but that's ok.
Yes, a lot of people do try to punt using relative font units as the best thing to do, however contrary to what they may say, you don't need to use it for everything.
Your end result should be a responsive web page. Your means to achieving this will differ based on the content you have.
Font scaling is a influencing factor that is most likely going to be around for a while, if you are worried about how it may affect your web page, ensure that only the elements that need to be scaled in relation to your font, will scale with your font.
"I'm tempted to just use pixels at this point for consistency." This is the logical conclusion in most cases, so go for it :)
That's because Chrome's behavior of setting a minimum font-size, so if you zoom-out, chrome will set the minimum font-size to 6px (12px for chinese and japanese version). So your div will have a minimum width as it depends on your base font-size (which can't be smaller then chrome's minimum).
See also:
Chrome will increase the font size when zooming out
[Edit] Additional Information:
Chromium Tickets & Discussions On this topic:
https://bugs.chromium.org/p/chromium/issues/detail?id=16875
https://bugs.chromium.org/p/chromium/issues/detail?id=36429
-webkit-text-size-adjust Support Dropped, so the viable solution for this behavior is not reliable anymore:
https://trac.webkit.org/changeset/145168/webkit
Don't use this CSS { font-size: 62.5%; } body { font-size: 1.6rem; } it causes more problems that it is worth, due to the fact that you will get different results on browsers that use different base font sizes. Just use this site to calculate the correct rem values. http://pxtoem.com/
This should give you consistent results.
https://jsfiddle.net/WizardCoder/gLkpz88q/3/
UPDATE
https://jsfiddle.net/WizardCoder/gLkpz88q/5/
I have faced this issue non-uniform browser zoom in zoom out on my project while setting the base rem . I have used rem in most of the place in the project .so,I had to set base rem based on the screen size dynamically. I will share few ways to set the base rem and issue I faced.The zoom in and zoom out inconsistent is caused because when we zoom out the screen width icreases and when we zoom in the the screen width decreases.So,if we set rem using the media queries or vw it will look inconistent while zooming in and out.
Fixed unit to set base rem like px ,%:
html{
font-size:68%;
or
font-size:16px;
}
pros:
same base rem on all the screen size.
The browser zoom in zoom out will be consistent
cons:
As it would be fixed value doesn't change based screen size.
sometimes the elements can't adjust on small screen size becoz of the specified base rem
Media queries to set base rem:
html {
font-size: 17px;
}
#media (max-width: 1536px) {
html { font-size: 15px; }
}
#media (max-width: 1920px) {
html { font-size: 13px; }
}
pros:
The base rem changes based on screen size.
cons:
The browser zoom in zoom out will be inconsistent
vw to set base rem:
html{
font-size:1vw;
}
pros:
the base rem will change based on the screen size and adjust. If zoom in zoom out is not important for you project.It would give perfect adaptation for the screen.
cons:
The browser zoom in zoom out will be consistent but the zoom in zoom out won't be working on few elements.so,it might look messy sometimes
Dynamic unit combination to set base rem:
html{
font-size:calc(.5em+.5vw);
}
pros:
Just need to adjust em and vw for base rem as we need for one screen.then base rem will change based on the screen size and adjust.
the zoom in and zoom out will be consistent.

What is the correct font-size to get desired results?

I've read many articles, but I'm not quite sure what is correct today. I want to set the font size properly, but I am not sure what to use.
I've seen body { font-size: 100% } and body {font-size: 62.5% }. I have also read that the font-size should be px or not be px.
What would be the correct way to do it today? If IE 6 [is outdated] and 7 are slowly becoming outdated, what would be the best way to set the font to cascade through the web site?
That is very much depending on your personal programming style and preference.
I for myself prefer to set the font-sizes in em. That gives me the advantage that I can adjust all font-sizes in the page, by changing one number in the body.
If you use a font size of 100% or 62.5% is also personal preference and depending on the layout. No one can tell you an optimal value, because no one knows what you personally like and want.
You should use 62.5%, if you want your font-sizes to be relative (Useful for text zoom in FF and IE)
body {
font-size: 62.5%;
}
p {
font-size: 1.2em; /* this is 12pixel */
}
Why 62.5%? It's a value that works in all browsers
This is less a question, but more general guidelines. This can also be applied to the line-height property, which can be pretty buggy in IE. As a UI developer, my workflow is as follows:
Set a Pixel value on body, generally 12px, 14px, 16px, or 18px. (this will be your default). I would very much avoid using a percentage for your default font-size. I also generally set a percentage or EM based line-height on the body element for all text.
Use EMs to define values for text. You may set your general paragraphs to 1.0em, and your first child to 1.25em to be slightly larger. Set your headers to appropriate sizes and so on. It really depends on the site you are working on, and your preference.
Remember, that with CSS once you set a height, it cascades down. If your default font-height is 12 px, and you set all of your divs to 1.33em, then set a sub element of your div to 1.25em, you are going to have a very strange font-size... It's not wrong by any means, but it's not best practice.
With a little practice this will keep you pretty fluid in knowing what your font-size is at any time, and works well across browsers.
Also with this practice, for the visually impaired who increase font-size, everything usually expands well, if you can imagine that all of your font-sizes would be percentage based off a default pixel size.
A good resource to follow for setting EMs after declaring a font-size on the body is pxtoem.com.
Hope this helps!

When setting the font size in CSS, why not set <body> to 6.25% so that px and em units are the same?

I was reading now about how it’s a good practice to set the font on <body> to 62.5%, so that later you can use the divide-by-10 conversion from pixel units.
But I was wondering: why not set <body> to 6.25%? Then you can use the same dimensions for em units as for pixel units, assuming the default browser font size is 16 pixels.
E.g.
body {
font-size: 6.25%; /* 1px */
}
p {
font-size: 12em; /* 12px */
}
Two issues.
I seem to remember that if you set your initial font size quite small using a relative unit like ems, if the user resizes the text Internet Explorer, the font size will change quite a lot between the settings.
It’s an odd phenomenon, and I’m not sure if it still occurs in IE, nor if you’re worried about users in IE who change the font size.
You’re potentially condemning yourself to re-setting the font size every time you nest elements.
An answer I wrote to another question tries its best to explain this, but in short, if you’re doing your font sizes in ems, you’re better off using font-size as little as possible, rather than making it ever-so-slightly easier to use font-size when you do.
For example: say you want all <li>s on the site to use a font size of 12 pixels.
li {
font-size: 12em;/* 12px */
}
If you then use the following HTML:
<ul>
<li>
<ul>
<li>
...
Then you need to do this:
li li {
font-size: .083em;/* 12px */
}
Otherwise the inner <li>s will be 12 pixels * 12 pixels = 144 pixels!
Ems aren’t pixels. Ems refer to a percentage of the nearest ancestor’s font size, whereas pixels refer to actual pixels. In my opinion, trying to turn ems into pixels is more confusing than the alternative. You’re better off setting <body> to the most commonly used font size on the site, only changing from that when you need to, and putting the intended size in pixels in a comment after your em-based declaration. (That way, it’s easier to tell later if you’ve got something wrong.)
(Of course, the only reason we avoid pixels is because IE doesn’t change the size of text sized in pixels when the user changes the font size in the browser. If you’re not worried about that, then just use pixels.)
Short answer: Don't do this. Use px to set font sizes. If you need a bigger font, use a larger number of px.
Long answer:
The idea behind setting the base font is make it obvious how big a ems and exs are. If your base font size is 10px, then 1.0em is 10px, 1.2em is 12px, etc. It seems simple enough. The idea breaks down as soon as a container changes the font size from the base. If you're in a div with the font size set to 20px, then all the sudden 1em is twice as big as it used to be.
It gets worse. People started suggesting that 62.5% should be used rather than 10px.
(Note that 16 * 0.625 = 10). This was suggested because specifying a percentage for font size is a workaround for an issue with old versions of Internet Explorer. The end user couldn't "zoom in" unless you used a percentage.
However, % (when applied as the default font) is an absolute unit. It may seem like a relative unit, but here, it's a percentage of the user agent's default font size, and font sizes are specified in points. This introduces a subtle and incorrect assumption about the user agent, namely that the screen resolution is 96 dpi. This assumption often results in text which looks like this:
Hey check me out, I'm too small to read!
To sum up:
Don't use hacks for old versions of IE (4 years is plenty of time to maintain backward compatibility; IE7 is four years old this month).
Don't make assumptions about your user agent's resolution, and don't set the body font size to a percentage.
If you need more precise typographical control, use a CSS framework like Baseline.
If you are doing this, you will have to make sure you resize every font on the page. If you miss anything, it will be tiny by default (1px).
Resizing every font may be more daunting then you imagine, because when you use relative font sizes, you have to be very specific.

FireFox 3 line-height

Firefox 3 has introduced a new behavior in which line-height, when unset, differs from how other browsers render it. Thus, a critical section maybe render too high in that browser. Setting a global percentage doesn't work, since it's basis is different. Setting a unitless value such as "1" doesn't work either. Is there some way to normalize this dimension?
The computed value of line-height: normal varies between platforms, browsers (and different versions of the same browser, as you state), fonts, and even different sizes of the same font (see Eric Meyer's article).
Setting a unitless value such as...
body {line-height: 1.2;}
...should work to normalize the spacing between browsers. If this is not working, can you provide a more-detailed description of your stylesheet?
It's hard (impossible?) to get "pixel-perfect" results, but in order to get results that are as predictable as possible, I try to use a line height that produces a nice round value when multiplied by the font-size. We can't know the user agent's default font size, but 16 pixels is somewhat common.
body
{
font-size: 100%;
line-height: 1.5;
}
If the user agent's starting font size is indeed 16 pixels then the line height of 1.5 comes out to a nice, even 24 pixels. Users can and do change the default font size or the page zoom, though, and different browsers have different methods of scaling the page. Nevertheless, I think I've had reasonable success for a majority of the users. If I can't make the line height come out exactly, then I shoot for a little above the integer rather than a little below, because some browsers seem to truncate values rather than round them.
Also, note that if you use a percentage for the line height, it behaves differently when the value is inherited.
body
{
font-size: 100%;
line-height: 150%;
}
p
{
font-size: 75%;
}
Starting from a base font size of 16 pixels, the line height will be 24 pixels. Within a <p> element the font size becomes 12 pixels, but the line height does not become 18 pixels, rather it remains 24 pixels. This is the difference between line-height: 1.5 and line-height: 150%. When body {line-height: 1.5;} is used, the line height for <p> is 18 pixels.
There is absolutely nothing you can do. Every browser has there way of rendering CSS and content. You can use a "Master" reset (as cowgod suggests), but even then, that's not ultimately going to fix the alignment issues. They are there because of actual rendering engine. Apple the CSS to your existing website and test it. Tell me if it makes pixel perfect across the board. It won't.
The only way to actually achieve pixel perfection is to implement specific CSS for specific browsers. Mozilla has the #-moz-doc, IE has it's own hacks, but none of these are part of the W3C specs, and we all know standards are important. So not much of an option.
As David said above, it's hard. I'm inclined to think impossible actually. And I've spent hours trying, trust me! Almost went mad more times than I care to count. It's a hard pill to swallow, but there is just no way around it, unless everyone used the same browsing engine (which would actually take the internet a great leap forward in my opinion). I mean, it wouldn't be that hard to slap whatever interface you want on your browser, so long as you plugin [gecko][webkit][presto][trident][whatever] to handle the backend... Since the good ones are all open source, you could merge the projects and really get going. People need to learn to play nice together ;)
You CAN solve this:
Set line height to 1, then zero in your text using padding-top and padding-bottom, and set height to auto.
.zeroed_in_element {
padding: 4px 2px 5px 2px;
height: auto;
line-height: 1;
}
You should always "reset" styles to eliminate all browser inconsistencies with element styles.
I like Eric Meyer's CSS Reset. Yahoo has one also.

Are there any practical reasons to use "em" instead of "pt" font size units? [duplicate]

This question already has answers here:
What is the difference between px, em and ex?
(4 answers)
Closed 1 year ago.
One CSS rule I have learned is that you should use the relative "em" font-size unit instead of the absolute "pt". The general idea is to set the font-size in your body tag to e.g. "94%" and then set all other elements with an "em" size like this. The reasoning is:
you can then change the relative size of all the font sizes on your site by modifying the body's font-size at one point
users themselves can modify the size of the fonts since they are defined in "em"
However, when using "em" instead of "pt" I constantly run into issues such as the following where an element with font-size gets embedded in another element with font-size and thus becomes tiny (in the case below one vocabulary word is .8 of .8 and the other is .8 of 1.2).
<html>
<head>
<style type="text/css">
body {
font-size: 94%;
}
p {
font-size: .8em;
}
li {
font-size: 1.2em;
}
.vocabulary {
font-size: .8em;
}
</style>
</head>
<body>
<p>This is an <span class="vocabulary">egregious</span> test.</p>
<ul>
<li>This is in a <span class="vocabulary">superb</span> list.</li>
</ul>
</body>
</html>
Of course in very simple, straight-forward HTML sites this is no problem, but in the real world with imported stylesheets that perhaps you didn't even make and with dynamic sites where controls are embedded in other controls all of them outputting HTML with perhaps in-line styling, I find websites with "em" unit font-sizes are sometimes impossible to maintain and the way to get font-size under control is to just convert everything to hard "px" sizes.
In addition, I just checked the four main browsers and each of them have hotkeys which increase and decrease the size of "pt" styled fonts.
So here are my questions:
is there any real-world reason why I should use "em" instead of "pt"?
is there trick in using "em" sizes so that I don't run into the embedded font-size issue above?
Depending on the country where you live, you might actually end up breaking the law using pt instead of em, depending on how hard your legislature want to enforce rules. Here in the UK, there is a disability discrimination act, which has been used to target companies where their websites have been rendered in a fixed font. This is treated as discrimination because it disadvantages the partially sited who may have increased their browser font sizes to compensate - but your site still renders fonts at the size you set, and not at the size they would expect.
Yes, it's harder to get to grips with relative font-sizes and fluid layouts, but if you want to comply with legislation, you have to take the time to get to grips with this.
For local government work in the UK, targets have been set to ensure that websites follow Double A guidelines, one of which states "Use relative rather than absolute units in markup language attribute values and style sheet property values". See here.
Even if you hard-code the font-size in pixel, you can still use em for unit to specify margin, length, etc.. , similar to using em quad to indent a paragraph in the printing press anyway.
Edit (After the poster changed from px to pt): If you want to be "pixel perfect", it's safer to go with px rather than pt, since different operating system has different dpi setting, and user change change dpi dramatically especially on Linux. PostScript point is defined to be 1/72 of an inch. An "inch" on screen can be anywhere between 72 pixels to whatever floats your boat.
From my experience as a web user who likes big text:
Specifying "pt" for font sizes is fine, as long as you don't specify element sizes in px/pt. Because when you do, and I increase the text size, half the text overflows ouside the element and way too often overflow is set to hidden.
This doesn't need to distort your layout -- just leave room for everything to grow downward. I can handle scrolling the page better than I can not seeing the text.
1) IE6 is still widely used and is unable to resize the fonts defined in px. => Usability issues. That alone is a no-no.
2) See CSS Units for example.
3) Most authors agree to say that pt is mostly a print unit: at worst, use them in print stylesheets, where the resize problem disappears...
See also http://www.killersites.com/mvnforum/mvnforum/viewthread?thread=4084
px : changes with your screen resolution and other dependent issues
em : irrespective of your screen resolution, it will be same for all
Some professional CSS developers that I know use "px" to define font sizes in their main stylesheet for modern browsers, then have a separate stylesheet for IE6 that specifies them using relative units. That way they achieve usability and allow font magnification on all browsers, but without having to compromise their design on modern browsers.
(They actually go farther than that: their IE6 stylesheet turns off most block formatting and just lays everything out using a generic, mobile-ish look. That way IE6 users can see a simple layout, and everyone else gets the professional look where blocks actually float correctly.)

Resources