Check out our Angular Book Series.

Can I use CSS calc() with vw and pixels?

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:


<html lang="en">
<body>
<div class="maindiv">
<h1>Hello You!</h1>
</div>
</body>
</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:


html, body {
height: 100vh;
width: 100vw;
background-color: grey;
margin: 0;
}

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:


.maindiv {
height: 100vh;
width: 50%;
background-color: white;
display: inline-block;
}

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:


margin-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.

How to center a div on a page using CSS?

There are a ton of posts about this topic, so I'm just writing this up in hopes I can remember it for this time. How can you center a div on a page? I'm working on a site that where the design requirements were fixed width. These days with mobile devices, I'm a much bigger fan fluid layouts, but that isn't this project.

So, my application needs to be some width, say 500 pixels, and centered within the screen. This is how I'm gonna do it. First, start with an HTML Page:


<html>
<head>
</head>
<body>
<div class="centereddiv">
<h1>Hello You!</h1>
</div>
</body>
</html>

There is an HTML body, with a div inside it, and some more content inside it. First, I'm going to add some CSS for the HTML and Body tags::


html, body {
height: 100vh;
width: 100vw;
background-color: grey;
text-align: center;
}

This sets the HTML and body tags to the height and width of the viewport area using the vh and vw units. I also gave a grey background and told it to center its contents with text-align: center.

Now add some CSS for the centereddiv:


.centereddiv {
width: 500px;
height: 100vh;
background-color: white;
display: inline-block;
text-align: left;
}

A width is specified. I used a pixel width, but this should work fine with a percentage width if you wish. The key part is the display being set to inline-block. This is the piece that tells this div to display in-line basd on the rules of the parent, and the parent uses text-align to center children. That is the magic.

I gave this a height of 100vh, and used text-align to left align the body, but neither matters for the purposes of this sample.

Try it out

It works pretty well.

How does the HTML5 Pattern Attribute work?

I came across a question on StackOverflow about how to use Angular to restrict input to capital letters. Back in my Flex days, I'd use the restrict attribute for that, but I've never had to do that for HTML5.

I did some digging and found that HTML5 introduced a pattern attribute. I thought this is probably exactly what is needed and Angular doesn't need to get involved at all.

I threw together a quick sample.


<input type="text" pattern="[A-Z]*" name="sampleinput" />

Unfortunately, that wasn't nearly as helpful as I thought it might be. It does not restrict input, only gives guidance. In Firefox, it will turn red if you enter invalid characters:

If we change to all caps, the Firefox red warning goes away. A nice visual queue, but it does not restrict the input like I wanted.

Chrome on the other hand provides no feedback:

I didn't continue testing in different browsers, but I imagine there is similar inconsistencies.

You can control the error message, but using the title attribute, and even write your own code against an invalid event.

As best I can tell, there is no HTML5 way to restrict the input into a text field. But, after some searching, I found a few ways to do this with Angular, most involve adding a validator on the input.

You can also use CSS to force the text to uppercase:


<input type="text" style="text-transform: uppercase;" name="sampleinput" />

However, that won't prevent the user from entering numbers.

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.