How to Write CSS Fallbacks for Vh Vw

How to write css fallbacks for vh vw

Your Code (and why it doesn't work)

Looking at your original code, I have a couple of comments:

-webkit-height: 5.2vh;
-moz-height: 5.2vh;
-ms-height: 5.2vh;
-o-height: 5.2vh;
height: 41px; /* The Fallback */

The prefixes, the -webkit- bit, only apply if there is a prefixed property by that name. Height doesn't have a prefixed property, so the browsers just ignore those declarations.

(Tip: You can check something like MDN to see what properties exist.)

Solution:

In this case, we can take advantage of the fact that, if browsers encounter a property or a value that they don't understand, they ignore it and move on. So, what you're looking for is something like:

height: 41px;
height: 5.2vh;

The browser sees height: 41px, as expected. It parses that, and knows what to do with it. Then, it sees height: 5.2vh. If the browser understands the vh unit, it will use that instead of 41px, just like color: blue; color: red; would end up being red. If it doesn't understand the vh unit, it will ignore it, and, because we defined the fallback first, the fact that the browser ignores the vh unit doesn't matter.

Make sense?

How can I gracefully degrade CSS viewport units?

  • 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/

Same properties in one class

This is absolutely fine. They are cascading, so the last (supported) style with the same level of importance always wins. It is a common case to override some CSS Rules with another class, so the browser has multiple instances of the same property to choose. So why shouldn't this be allowed in the same class? I can see no disadvantages, except for the extra line of code, but if you have to support old browsers, you need a fallback.

I'm assuming you know that 500px will not always be the same width/height as 50vw/vh, so yeah, a disadvantage would be, that it may looks different in older browsers. But from a syntactic view, there is nothing wrong.

Same properties in one class

This is absolutely fine. They are cascading, so the last (supported) style with the same level of importance always wins. It is a common case to override some CSS Rules with another class, so the browser has multiple instances of the same property to choose. So why shouldn't this be allowed in the same class? I can see no disadvantages, except for the extra line of code, but if you have to support old browsers, you need a fallback.

I'm assuming you know that 500px will not always be the same width/height as 50vw/vh, so yeah, a disadvantage would be, that it may looks different in older browsers. But from a syntactic view, there is nothing wrong.

Discussion: Why use new CSS features if you have to write fallbacks anyway?

Here is some arguments why.

  • You could do a lot more with design. Think about all the workarounds you need to implement in order to have something simple as 100vh... Your designers will be happy if they have you on their team.
  • Lot less duct taping solutions, see above.
  • New features makes your code better, maintenance will be a lot better, you code in general will be more clean. This actually means less work in the feature.
  • Performance, browsers that support new features will have lot less code to use, this is not true ofc for every new feature out there.
  • More work with fallback solution, yes, that might be true. But if you are always writing the same fallback solutions to the same features then you are doing something wrong, search the web, there might be a solution already there, if not make your own internally and reuse it on other projects, thus you will have to make a fallback solution only once.
  • You want your developers happy, if there is a way to use new features (and there is almost always a way), you should use it. Motivation kind of a thing.
  • If NOT then those features will never get used anyway since people will stick the old ways thus there is no need for browsers to implement in the new versions because guess what no one is using those new features thus we don't need them. But we all know we need them.
  • New features will eventually becomes standard (if we actually use them), you want to have team that is already proficient in those new technologies, thus you can sell yourself better to the client.

As for grid css layout, check this one --> https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement

Also, this kind of question is better fit for the Quora or something similar, not stack.

CSS3 100vh not constant in mobile browser

Unfortunately this is intentional…

This is a well know issue (at least in safari mobile), which is intentional, as it prevents other problems. Benjamin Poulain replied to a webkit bug:

This is completely intentional. It took quite a bit of work on our part to achieve this effect. :)

The base problem is this: the visible area changes dynamically as you scroll. If we update the CSS viewport height accordingly, we need to update the layout during the scroll. Not only that looks like shit, but doing that at 60 FPS is practically impossible in most pages (60 FPS is the baseline framerate on iOS).

It is hard to show you the “looks like shit” part, but imagine as you scroll, the contents moves and what you want on screen is continuously shifting.

Dynamically updating the height was not working, we had a few choices: drop viewport units on iOS, match the document size like before iOS 8, use the small view size, use the large view size.

From the data we had, using the larger view size was the best compromise. Most website using viewport units were looking great most of the time.

Nicolas Hoizey has researched this quite a bit: https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html

No fix planned

At this point, there is not much you can do except refrain from using viewport height on mobile devices. Chrome changed to this as well in 2016:

  • https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/BK0oHURgmJ4
  • https://developers.google.com/web/updates/2016/12/url-bar-resizing

JavaScript calculate with viewport width/height

Based on this site you can use the following util functions to calculate your desired values as a function of a percent of screen width or height:

function vh(percent) {
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
return (percent * h) / 100;
}

function vw(percent) {
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
return (percent * w) / 100;
}

function vmin(percent) {
return Math.min(vh(percent), vw(percent));
}

function vmax(percent) {
return Math.max(vh(percent), vw(percent));
}

console.info(vh(20), Math.max(document.documentElement.clientHeight, window.innerHeight || 0));
console.info(vw(30), Math.max(document.documentElement.clientWidth, window.innerWidth || 0));
console.info(vmin(20));
console.info(vmax(20));

CSS Calc Viewport Units Workaround?

Before I answer this, I'd like to point out that Chrome and IE 10+ actually supports calc with viewport units.

FIDDLE (In IE10+)

Solution (for other browsers): box-sizing

1) Start of by setting your height as 100vh.

2) With box-sizing set to border-box - add a padding-top of 75vw. This means that the padding will be part f the inner height.

3) Just offset the extra padding-top with a negative margin-top

FIDDLE

div
{
/*height: calc(100vh - 75vw);*/
height: 100vh;
margin-top: -75vw;
padding-top: 75vw;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: pink;
}


Related Topics



Leave a reply



Submit