Viewport Unit Bug iOS Safari

The CSS viewport unit is a practical way to scale elements relative to the size of the device viewport. However, there is a mysterious bug in iOS Safari that occurs when content inside an element changes.

What are CSS viewport units?

Viewport units vwviewport width and vhviewport height are useful measurement units that scale elements in CSS relative to the size of the viewport. By example, it can be used to scale responsive typography, or for setting the size of certain page elements to fit exactly within the display viewport.

/* Set font-size based on viewport width */
h1 { font-size: 6vw; }

/* Set height of slideshow element to fill 100% viewport height */
.slideshow { height: 100vh; }

/* Set max height of an image to 95% of the viewport height */
.lightbox img { max-height: 95vh; }

Sweet So what's the problem?

The problem occurs when dynamically changing content in an element that is sized with vh in CSS. In iOS Safari, the height of the element accumulates to equal the original height of the element in addition to the height of any new data appended by javascript. This basically renders the measure incorrect, as 100vh will render taller than 100% viewport height, even if the content is smaller. In all other browsers, the measure works as expected.

Fix

Although there is no general fix for this issue, we added a basic workaround for our specific case. After our full-viewport javascript slideshow initiates, we can safely remove the CSS rule on iOS Safari, thus preventing any miscalculations.

// Remove min-height on iOS after slideshow initialization
var iOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true;
if(iOS && $('.slideshow').css('min-height') == '100vh'){
  $('.slideshow').css('min-height', '0');
}

Related Links

Viewport relative unit strangeness in iOS 6 - Thatemil.com

Sizing with CSS3's vw and vh units - Snook.ca

Viewport Sized Typography - Css-tricks.com