Quick Note: Using Viewport Units
These little darling units allow for some really nice effects and typographical work. We'll explore what they are and a couple effects we can use them on. ## vh and vw The two basic units for viewport measurement are `vh` and `vw` which track like so: - `vw`: 1/100th (1%) viewport width - `vh`: 1/100th (1%) viewport height The units will remain constant. 1/100th of the viewport width will remain 1/100th regardless of how wide or narrow the viewport becomes. to make an element span half the screen horizontally we could do something like this: ```css hero { width: 50vw; } ``` There may also be elements like a masthead that we want to place in the top 20% of the screen we could combined with `position: fixed` to do something like this: ```css .masthead { height: 20vh; position: fixed; } ``` ## vmin and vmax These two units are a little more complicated, they will take the value from whatever side matches the minimum or maximum value. - `vmin`: 1/100th (1%) of the smallest side - `vmax`: 1/100th (1%) of the largest side I've always had a hard time when it comes to choosing how/when to use `vmin` and `vmax`. The default value for these will also depend on the device's orientation and how much has the user resized the browser window: `vmin` uses the ratio of the smallest side. If the height of the browser window is less than its width, `1vmin` will be equivalent to `1vh`. Otherwise `1vmin` is `1vw`. `vmax` is the opposite: `1vmax` equals `1vw` if the viewport is wider than it is tall; If not `1vmax` is equal to `1vh`. This means we can use these values inside device orientation media queries (`(@media screen and (orientation: portrait)` or `@media screen and (orientation : landscape)`) since these units are already designed to take the value from either the height or the width. ## Some examples Here are some examples of what you can do with these units. ### Truly responsive content A couple years ago I came across a Pen from [Brian Haferkamp](https://codepen.io/brianhaferkamp/) called [2-Up Magazine Layout](https://codepen.io/brianhaferkamp/details/xEypqR) and I was amazed at the level of complexity he crammed into the Pen and the attention to detail that he paid too little details such as responsive sizing of the content and how the 2-column layout would automatically resize itself in narrower viewports. I took the idea, having a fixed image next to scrolling text. I think I've finally figured out what the technique is and how to implement it. This is a stripped down version of [my pen](https://codepen.io/caraya/full/aGVPvL/). The first thing we do is set the wrapper container to be a flex container using `display: flex`. We don't need to set the children items as `flex-item`. This is automatically done when we set the parent element's display. [background-size: cover](https://css-tricks.com/almanac/properties/b/background-size/) tells the browser to cover the full dimension of the container, in this case, 100vh and 50vw. QWe can play with the image positioning using [background-position](https://css-tricks.com/almanac/properties/b/background-position/) to place different parts of the image in the viewport we're covering. The [flex](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-13) property is the shorthand for [flex-grow](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-10), [flex-shrink](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-11) and [flex-basis](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-12) combined. With these values we're telling `.poster-image` elements to take 50% of the parent container size before other elements are distributed in it. For the `.text` element(s) we give them padding and a left margin. We also make sure that they are at the top of the stacking order. ```css .article-wrapper { display: flex; } .poster-image { position: fixed; background-image: url("path/to/image"); background-size: cover; // background-position: center; height: 100vh; width: 50vw; flex: 0 0 50%; z-index: 1; } .text { padding: 100px 60px 60px; margin-left: 50%; z-index: 10; } ``` The HTML is a series of div containers that hold: - The article wrapper element (`.article-wrapper`) - The poster image (`.poster-image`) - The text of the article (`.text`) - And the article content itself (`article`) ```html