Use Viewport Relative Units

I just learned about viewport relative units, vh, vw, vmax, vmin.

Amazing. Finally an easy way to do full height elements via 100vh == 100% viewport height.

Only problem? It blows up explosively on IOS devices.

I love the concept though, so I just created a simple coffeescript class which can be invoked directly or via data tags to trigger widths and heights correctly by converting an inline data attribute to explicit calculations on resize.

Parsing CSS for these new units was too much overhead.

<div data-viewport-styles="width: 100vh; height: 50vw;"></div>

class root.utils.ViewportHeight
‘The VH unit is not well supported. Use data-tags instead.
data-viewport-unit="line-height: 100vh; height: 100vh;’
constructor: ({@element, @styles}={}) ->
@$element = $ @element
@$window = $ window

_getStyles: ->
# get styles as array
if not @_styles
styles = {}
for style in _.filter(@styles.split(‘;’), Boolean)
[key, value] = style.split(‘:’)
styles[key.trim()] = @_getValue(value)
self._styles = styles
return self._styles

_bindHandlers: ->
$(window).resize _.debounce(@onResize, 50)

_getValue: (value) ->
# given a unit like 400vw or 400vh, set it to absolute pixel values
# map viewport units to viewport unit conversion functions
viewportUnitMap = {
‘vh’: @_vh,
‘vw’: @_vw,
‘vmax’: null,
‘vmin’: null,
value = value.replace(‘;’, ”).trim()
for unit, func of viewportUnitMap
if unit.substr(value)
return func(parseInt(value))

_vh: (value) =>
@$window.height() * value/100

_vw: (value) =>
@$window.width() * value/100

_vmax: (value) =>
return Math.max @_vh(value), @_vw(value)

_vmin: (value) =>
return Math.min @_vh(value), @_vw(value)

onResize: =>
# window has been resized. update CSS values of vh/vw equivalents
@$element.css @_getStyles()

$("[data-viewport-styles]").each (index, el) ->
new root.utils.ViewportHeight
element: el
styles: $(el).data(‘viewport-styles’)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s