The Magical Powers of VMIN unit. 🎩

The Magical Powers of VMIN unit. 🎩

  • toucaan
  • 4 minutes
  • March 1, 2022

Welcome to the newest chapter on the Toucaan Intrinsic CSS framework.

This chapter will focus on some of the hidden properties of the viewport unit vmin. We would discuss the effect of those properties on digital content and then devise a strategy to use vmin in regular day-to-day web design.

This post will also demonstrate that the suggested methodology using vmin is much simpler and more scalable than most commonly accepted techniques such as the responsive typography. Frankly, the formula for responsive typography is unwieldy and approximated; it never appealed to me due to its severe limitations.

Hopefully, the reader will take some new insights into how vmin works and visualize how it can become–or more or less is–the backbone of intrinsically scalable typography for block-scoped components.

Let us dive into vmin!

Demo → Red Goose is a live example (albeit still a work in progress) to look at what vmin based typography looks like. It is in production mode, so we are close to the final release.

Disclosure → Red Goose is also the main sponsor of the Toucaan CSS Framework.

The soul of intrinsic web design

One of the ways intrinsic differs from responsive is the notion of block-scoping typography to a component. Or, in traditional speak– block-scoping the font size of the text to the size of an element.

Examine closely the role of the vmin unit in the example below:

--side: 50vmin;

.square {
  width: var(--side);
  height: var(--side);
  font-size: calc(var(--side) / 10);
}

As you can see from the code above, the font size of the text within the .square element is dependent or rather “scoped to” the dimension of the square element. This may seem simple to explain, but it is anything but simple. Please do spend some time on this!

See the Pen Blockscoped typography. (Toucaan CSS Framework) by Marvin Danig (@marvindanig) on CodePen.



The font size of the text ‘hello world’ scales precisely in proportion to the edges of the square element. Therefore, resizing the browser window does not trigger content reflow within the containing element–the square.

We could pin the font size to the width of the component instead. And then adjust the line height of the entire body of text to some integer factor of the total element height.

You know, give a height: calc(n-times-height-of-each-line) to the element. It wouldn’t be a stretch to say here that we could even introduce line-tracking on the web this way. Wouldn’t that be an excellent solution for the shrinking attention span of all humanity?

…but, but what about the level of support?

No problem at all. vmin is defined as 1/100th of the shorter side of a viewport. So even without looking at caniuse, we can implement a --vmin custom property like so:

@media only screen and (orientation: portrait) {
  :root {
    --vmin: calc(100vw/100);
    --vmax: calc(100vh/100);
  }
}

@media only screen and (orientation: landscape) {
  :root {
    --vmin: calc(100vh/100);    /* Axiom: 100vh of landscape === 100vw of portrait. */
    --vmax: calc(100vw/100);
  }
}

:root {
  --vmin: 1vmin;
  --vmax: 1vmax;
}

Now, the custom property --vmin is available on our css to use anywhere.

So what is with the hidden properties then?

There are three unique qualities of the vmin css unit that may not be immediately evident to a developer:

  1. vmin is always from the shorter side of the screen. So in mathematical speak, it is from the breadth (B) of a rectangle and not the length (L). Read more about how this is used on our CSS router while orientation matching.
  2. Upon resizing the browser window, the rate of change exhibited by vmin is much lower than the rate of change on vmax, i.e. Δvmin « Δvmax. This makes vmin far more straightforward to scale with than the vmax.
  3. For a rigid viewport, the value of a vmin is a constant no matter what the underlying pixel resolution or setting of the display might be. Meaning the physical measure of 1vmin unit on the screen of the following two mobile phones will be equal even though both have unequal screen resolutions or dpi:


Device resolution does not matter to the vmin. If the physical size of the devices is equal, the size of 1vmin would also be.


Brilliant.

How to use `vmin` on our css then?

A strategy of how the vmin unit could be used on your web application today is committed on the Toucaan CSS Framework. But there are several approaches to choose from and YMMV.

What I do on Toucaan, and subsequently on Red Goose as well, is apply the strategy of testing for the “squarishness” of a given rectangular screen. The more squares one could fit on a rectangular screen, the more ultrawide it becomes.

I ask: How many perfect squares of full height or half-width can be displayed side-by-side on the rectangular screen in landscape mode? Is the length L (width of the window in web design terms) of the rectangular screen twice as large as its breadth B (the height)?

@media (min-aspect-ratio: 2 / 1) { 
/* If the length/breadth ratio > 2, we can fit two squares of full height on the screen.  */
  :root {
    --edge: 100vmin; /* The shorter side */
    --fs: calc(var(--edge) / 100);
  }
}

@media (max-aspect-ratio: 2 / 1) { /* Length/Breadth ratio < 2 */
/* If the length/breadth ratio < 2, then we can fit only one square of full height on the screen but we can still fit two squares of half width each side-by-side.  */
  :root {
    --edge: 50vw;
    --fs: calc(var(--edge) / 100);
  }
}

Then we can use the --fs custom property to scale the font size of the text within the body of the page easily with a rule like font-size: calc(4 * var(--fs)) or something more elaborate.

That’s it, and that’s the formula for scalable intrinsic typography.

I think vmin based design systems can allow developers to infuse deeper intrinsicality into their user interfaces. It can lead to a more strongly controlled design experience with deterministic UIs that offer better control to the designer than otherwise.

For example, I can confidently say that my homepage on Red Goose will never fall below the fold because I’m using --vmin & --vmax units to establish the height of the page, and I scale the content within with those units too.

Conclusion:

To sum up this post, I’d say that vmin is the most genuine calling of intrinsic typography. I know we have become comfortable with the other older css units like px, em, and rem and have gone far down the path of complex assumptions, but I think vmin deserves a chance.

It is the soul of intrinsic web design that shows much promise.

👉🏻 Further reading: Understanding-vMin-and-vMax-in-CSS

This post on Hacker News: https://news.ycombinator.com/item?id=[number whenever it gets shared.]


By Marvin Danig, CEO & Founder of Bubblin Superbooks and the Red Goose.

About the author

Marvin Danig

I write code with my bare hands. 💪🏻 Yammer about Bubblin all day.

https://bubblin.io/marvin