I was working on a problem today where we wanted to offset the position of an ng material sidenav. The problem was we didn't know what we would want the offset to be, it would depend on the browser size on the clients computer which will most likely be variable.

I suggested using calc() with vw, subtracting the width of our flyover, dividing it by 2, and then using that to set the margin. Surprisingly this worked swimmingly, because I felt like I pulled that idea out of nowhere.

First of, what is vw? It stands for view width and references the width of the viewport. It's brother is vh, which stands for view height but isn't relevant to today's problem.

What is calc()? It is a CSS construct that allows us to make calculations at runtime.

Let's start with some simple HTML:

view plain print about
1<html lang="en">
2<body>
3<div class="maindiv">
4 <h1>Hello You!</h1>
5</div>
6</body>
7</html>

There is an HTML, a body, a div, and some content inside the div. First, I'm going to expand the HTML and body the full height and width of the available viewport:

view plain print about
1html, body {
2 height: 100vh;
3 width: 100vw;
4 background-color: grey;
5 margin: 0;
6 }

Do this with CSS, of course.

Now, let's look at the maindiv. I'm going to size it to 50% width, and 100vh height:

view plain print about
1.maindiv {
2 height: 100vh;
3 width: 50%;
4 background-color: white;
5 display: inline-block;
6 }

I also gave it a background color of white, to offset it from the background of the full app, and the display is inline-block which means it will accept layout cues from the parent, in this case the body tag.

In order to get the item to center, we'll use calc() with the margin:

view plain print about
1margin-left: calc((100vw - 50%)/2);

The calc takes the full 100vw and subtracts 50%, the same width of the maindiv. Then it divides that number in half. The resulting value--calculated at runtime--essentially centers the maindiv on the page:

Play with the same here.

I feel a slight tinge of success when off the cuff ideas like this work elegantly.