Alignment in CSS: text and vertical alignment
Tags: css, tutorial, beginners
Published: 2019-08-04 23:11:36

*Cover photo by Alex Wong.*

### This is the beginning of a long journey to learn how to get things to finally, finally align properly on our webpages.

Today's tutorial is about two properties: `text-align` and `vertical-align`. Text align is a very simple property, often the first to be learned by beginners. Vertical align seems to be its simple counterpoint, but can be deceptive due to its complex rules and is an early stumbling block for many.

# 📌 Text align

The purpose of `text-align` is to align text *horizontally*. Play around with it:

{% codepen https://codepen.io/tchaflich/pen/OKxrVx %}

If you've worked with any sort of text editor before, these options will be strikingly familiar.

There are more options coming soon - for example, `start` and `end`, which depend on the text direction, aligning via a specific character (such as a decimal), and `justify-all`, which forces the last line of text to be justified. These vary widely in support as of the authoring date (Aug 2019), as they are currently still editor's drafts in terms of specification - so make sure to check compatibility tables before using anything fancy.

References & further reading for text-align:
* [MDN: text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align)

# 📌 Vertical align

As you might have guessed by the name, the purpose of `vertical-align` is to align text *vertically*. In the sample below, I have highlighted some key plant-related phrases; the buttons toggle the vertical align property of these highlights.

{% codepen https://codepen.io/tchaflich/pen/gVGZgG %}

If you're applying vertical-align to `display: inline` or `display: inline-block` elements, then you will be able to align them with each other. You can align anything that can flow horizontally, as long as it has a valid display property set. Text, images, icons, buttons, inputs...

### When using `vertical-align` on inline or inline-block elements, the alignment is relative to sibling elements in a horizontal line, rather than the parent element.

Vertical align also works on tables (as well as elements with display set to table-cell). Here's a sample table to play around with:

{% codepen https://codepen.io/tchaflich/pen/wVrVKp %}

An important note:

### ⚠️ Vertical-align does not align block elements. ⚠️

So if you're thinking... "wait, vertical-align didn't work for me! Why are you telling lies?", look into your element's `display` property. **Vertical-align is not an all-purpose way to align everything.** Since block level elements cannot have an in-flow sibling on the same line as them, they will not be aligned. Block elements *can*, however, have children inherit their vertical-align property; it's not strictly invalid, just useless for positioning.

If you remember the days of table-based layout (way, *waaaay* back... hopefully), you might remember the [`valign`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td#attr-valign) *attribute* on table cells. It's speculated that the `vertical-align` property was created specifically to emulate the behavior of this attribute.

#### tl;dr

Use this for vertically aligning text, images, icons, or other things that display "in line" with each other horizontally. Unless you're using it in a table, vertical align changes items' behavior relative to *each other*, rather than with respect to their parent element.


References & further reading for vertical-align:
* [MDN: vertical-align](https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align)
* [Vertical-Align: All You Need To Know (CSS)](https://christopheraue.net/design/vertical-align)
* [Understanding vertical-align, or "How (Not) To Vertically Center Content"](http://phrogz.net/css/vertical-align/index.html)

## Bonus vertical align: A tall ghost 👻

Here's a neat trick that uses vertical align. I don't use it in production anymore now that flexbox is well-supported, but it's still a good exploration of how vertical align works.

This trick is an extension of the fact that vertical align works to center inline-block elements *with one another*.

![An illustration on graph paper of the container setup. There's an inner container (complete with drawn cat), an outer container, and a "tall ghost" dotted line on the left.](https://thepracticaldev.s3.amazonaws.com/i/xjmaijcc5g179ndmikox.png)

We have:

* An outer container, larger than the inner container
* An inner container that we want to center vertically
* An invisible "tall ghost" container that only assists with alignment

{% codepen https://codepen.io/tchaflich/pen/RzRLoG %}

The important bits:

* The tall ghost and inner container are **both** `display: inline-block` and `vertical-align: middle`
* The tall ghost is 100% height (that's why it's tall!)
* The tall ghost is zero width, to make sure it doesn't throw off alignment (it's invisible)


The invisible aligning element is *set* to be the height of its parent with `height: 100%`, so whatever is aligned vertically with the "tall ghost" will *happen* to align with its parent block element. The two elements inside the container are both inline-block, and so they are available to vertically align with each other. They're both set to `vertical-align: middle`. And so, the inner container that we want to align (the cat) sits in the middle.

Now, that code is a bit messy, so we can clean it up by using [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/::before):

{% codepen https://codepen.io/tchaflich/pen/mZEBOO %}


There are a couple other small notes:

* The `content` attribute containing a space is just to make sure the element can render in all browsers.
* While the width and height are explicitly set in this example, they do not need to be; as long as the inner content doesn't overflow the parent, this trick will work, since it's based on percentage.
* The cat is horizontally centered with `text-align: center` because I think it looks nice. This is optional.

![Bob Ross: "I'm glad you could join me today."](https://thepracticaldev.s3.amazonaws.com/i/j9ygt43b5h3mewoo605m.gif)

Anything else you'd like to know about these properties? Any requests for the next entry in the series? I have a *lot* planned... it turns out CSS has a lot of ways to align stuff. (How come none of them ever work? 🤔)