8 ways to center elements with CSS
Tags: css, beginners, webdev
Published: 2021-05-17 06:15:24

Centering elements in CSS sometimes causes a headache, even to experienced developers. There are many different situations and many different solutions. Sometimes it is best to choose one over another but other times it is a matter of personal preference. To make the right decision, we need to know what CSS has to offer and the pros and cons of each given option. In this post, I have gathered 8 of them so let’s look at them in more detail.


## 1. Flex

This one is in my opinion the most simple solution. You only need to add three properties to a parent element and the child will be centered inside of it. The `align-items` property aligns the child vertically, while the `justify-content` aligns it horizontally.

```css
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}
```

You can use this solution in almost every situation. Downside? IE10 and bellow do not support justify-content and align-items properties.

[![align-items flex](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfjy3uwkeimay60d8r5v.png)](https://caniuse.com/?search=align-items)

[![justify-content flex](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqhl1vl6i1hnzta6vg3i.png)](https://caniuse.com/?search=justify-content%3A%20center)

In the past three years, I never had to support IE10 or lower so chances are you do not need to worry about it as well. This makes flex solution a very good fit for the job.

| Vertical | Horizontal | Known heights | Browser support |
|:--------:|:----------:|:-------------:|:---------------:|
| ✅        | ✅         | no            | IE11+           |

## 2. Grid

The grid solution is very similar to the flex one. Even the code is almost the same.

```css
.parent {
  display: grid;
  justify-content: center;
  align-items: center;
}
```

It behaves the same as the flex solution, except for the browser coverage. If `justify-content` and `align-items` worked in IE11 for flex, they do not work for the grid display.

[![align-items grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nim3gzgc7kebm603hizc.png)](https://caniuse.com/?search=align-items)

[![justify-content grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s44qcgckgmx1u5oaia03.png)](https://caniuse.com/?search=justify-content%3A%20center)

This might be a good solution if you do not have to cover IE at all and if you prefer using a grid over flex.

| Vertical  | Horizontal | Known heights | Browser support  |
|:---------:|:----------:|:-------------:|:----------------:|
| ✅        | ✅         | no            | IE not supported |

## 3. Position

If the parent has a set height or min height, then using position might be a good solution. A child with the `position` property set to absolute will be taken out of the flow. This means that the child's height will not affect the parent's height. Knowing that it is not wise to use this approach to align a box with text that can have a different length. This code will align a child horizontally and vertically:

```css
.parent {
  position: relative;
  /* add some height to the parent element, for example: */
  min-height: 200px;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
```

If you only wish to align an element vertically use this style for the child instead:

```css
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
```

or this one to align it horizontaly:

```css
.child {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
```

All used properties for this solution are very well-supported on all browsers. Note that the `transform` property is not supported by IE8 and lower but you most likely don't need to worry about it.

| Vertical  | Horizontal | Known heights | Browser support  |
|:---------:|:----------:|:-------------:|:----------------:|
| ✅        | ✅         | no             | IE9+             |

## 4. Margin

Using a margin to horizontally align a block element is also very popular. It is often used to align layout elements like containers, but it is a good fit for any block element. The code is very simple:

```css
.child {
  margin: 0 auto;
}
```

This approach will allow you to align an element horizontally. To also align it vertically you can use some other solution, like padding for example.

| Vertical  | Horizontal | Known heights | Browser support  |
|:---------:|:----------:|:-------------:|:----------------:|
| ✅        | ❌         | no            | very good        |

## 5. Padding

You can use padding to center an element vertically and horizontally. Although very simple, padding is rarely a fit solution to center elements. The reason for it is that it relies on fixed heights of child and parent which are rarely given. To center an element with padding you need to divide equal padding value to all sites of the element:

```css
.parent {
  height: 300px;
  width: 400px;
}

.child {
  height: 50px;
  padding: calc((300px - 50px) / 2) calc((400px - 50px) /2);
}
```

The sum of height and vertical padding determines the child's vertical position. The child is centered if the sum is equal to the parent's height.

```css
.parent {
  height: 300px;
}

.child {
  height: 50px;
  padding: calc((300px - 50px) / 2) 0;
}
```

For the horizontal position, the same applies. If the sum is equal to the parent's width, the child is centered.

```css
.parent {
  width: 400px;
}

.child {
  height: 50px;
  padding: 0 calc((400px - 50px) / 2);
}
```

| Vertical  | Horizontal | Known heights | Browser support  |
|:---------:|:----------:|:-------------:|:----------------:|
| ✅        | ✅         | yes           | very good        |

## 6. Text align

The text-align property can be used to align any inline element. This solution is very good at aligning items like text, images, buttons, and links. Many of them have a display set to inline-block by default but you can also change the display property.

```css
.parent {
  text-align: center;
}

.child {
  display: inline-block;
}
``` 

It is a very simple solution but it will only allow you to align the element horizontally. To align it vertically, a good pair would be to use the vertical-align solution.

| Vertical  | Horizontal | Known heights | Browser support  |
|:---------:|:----------:|:-------------:|:----------------:|
| ❌        | ✅         | no             | very good        |

## 7. Vertical align

The vertical-align property is the one that I struggled to understand the most. It controls the alignment of elements that are next to each other in one line. The elements need to have an inline or inline-block display for it to work. The use case for this solution would be to align icons with text.

```css 
.parent > .child {
  display: inline-block;
  vertical-align: middle;
}
```

This will only align elements along with the line-height of the highest element. If you want to vertically align the element relative to the parent's height, you can do it like this:

```css 
.parent {
  display: table-cell;
  vertical-align: middle;
}

.child {
  display: inline-block;
}
```

As the property's name suggests, it only allows you to center elements vertically. You can use text-align property on the parent to center them horizontally as well.

| Vertical  | Horizontal | Known heights | Browser support  |
|:---------:|:----------:|:-------------:|:----------------:|
| ✅        | ❌         | no             | very good        |

## 8. Line height

Last but not least, you can also align an element with the line-height property. To do that a child needs to be an inline or inline-block element. The element is always vertically centered inside of its line-height. That means that when the line height is as high as the parent, the element is vertically centered inside of it.

```css
.parent {
  height: 100px;
}

.child {
  display: inline-block;
  line-height: 100px;
}
```

Line height allows you to only center the element vertically. To center it horizontally you can use the text-align solution. The best use case for that solution are elements like icons, buttons, or links. Because you are messing up with the line height, use it on elements that will always stay in one line.

| Vertical  | Horizontal | Known heights | Browser support  |
|:---------:|:----------:|:-------------:|:----------------:|
| ✅        | ❌         | yes           | very good        |

##Summary

As we can see, there are many ways in which you can center an element and I am sure there are others as well. The flex and position solutions are my go-to options although I use others as well sometimes. Do you have a go-to solution? Let me know!