tutorials:~ How to Center with CSS in 2019

Centering with CSS, vertically and horizontally is a popular problem. Today, in 2019, there are many solutions to this problem, tailored to different use cases and browser support. Let's explore them!

Horizontal Centering

Center Text and Inline Elements with text-align: center

This technique is commonly used to center text, one or multi-line. You can also center images with it.

Interestingly enough, you can also use this technique for centering divs as well, if they are set to display: inline-block

Caveat: reset the centered block text-align if you don’t want the contents to be centered as well. Overall for non-inline elements it is better to use the margin:0 auto.

Center Block Elements Horizontally with margin: 0 auto

This is another centering technique, which is also almost as old as the web as we know it. It works great on blocks as well as any elements with set width less than 100%. That is, if you set width on an inline element, you can apply this technique to it. Browser will distribute the remaining place around the element automatically. Caveat: if the browser is resized and its width becomes smaller than the blocks set width, you may see horizontal scrollbar. To avoid that set max-width. Take a note though that max-width is supported IE7+

Vertical Centering

Center single lines of text (and sometimes images) with line-height

Center an inline element with line-height. If your parent block has set height value, make sure the line-height is equal to it, otherwise the element will be lower (if line-height is bigger) or higher (if line-height is smaller) than expected. This technique works best on one-line texts, which will not wrap, for example in buttons. Line-height essentially sets a line of the text above and below the current texts, whose heights equal to half of the line-height. If the line-height is much greater than the font-size, you can try use only line-height to center. Set line-height to be greater than the font size. Also note that it centers based on lowercase letters, so the text line with capital letters may appear not centered for visual perfectionists, even though it seems to be used everywhere just like that. So you’ll have to add paddings to even it out.

Example of centering one line of text (or other inline-element) with line-height.

<button class='main-button white br2' style='line-height:50px;height:50px;padding:0 10px;'> I'm a button with centered text </button>

Add same top and bottom paddings

Just set padding-top and padding-bottom to the same value and call it a day.

Example of using equal paddings.

This texts have padding-top equal to padding-bottom

and so appear centered vertically

Use HTML and CSS tables

By 2011 HTML tables ruled the CSS centering world. We still use them in email templates, sometimes even with deprecated align and valign attributes (see Outlook issue ).

However, if you hate non-semantic layout, CSS2.1 spec offered display: table, display: table-cell already in 2011. As the "table" name may suggest, these properties mimic table layout. To center element vertically, you have to place it in a container with display: table and an inner element with display: table-cell and vertical-align: middle.. The latter is used on the HTML tables as well since HTML5.

It is an easy solution for better semantics of the layout, combined with the centering power of the tables. Using it, you don't have to set the child element height or control anything else except display and vertical-align properties.

Example of centering vertically with CSS tables attributes:
<main style="display: table;"> <div style="display: table-cell; vertical-align: middle; text-align: center;"> This text is centered vertically and horizontally as well. </div> </main>

Center vertically with a ghost element: Michał Czernow hack

This is a technique, the author of which is known probably thanks to this CSS tricks article To center an inline-block element (multi-line text, for example) vertically, you can use a ghost element. It stretches along the parent container height and centers the element with vertical-align: middle. You can use a span, or even a pseudo-element. display property to inline-block, vertical-align:middle, height: 100%.

Example of centering with ghost pseudo-element.

Let's center a ghost emoji description in a gray container. To center it vertically I added display: inline-block and vertical-align: middle to the description. Also I added a pseudo element with display: inline-block, vertical-align: middle and height: 100% to span full height of its parent.

👻 Ghost. Boo!
A ghost emoji, trying to scare someone. Might also be a halloween costume. Emojipedia

.ghost-container::before { content: " "; display: inline-block; height: 100%; width: 1%; vertical-align: middle; } .di { display: inline-block; } .v-mid { vertical-align: middle; } .tc { text-align: center; }
<div class='ghost-container tc'> <p class='di v-mid'></p> </div>

Centering both Horizontally and Vertically at once

Set Negative Margins

This technique will work for you if you are fine with calculating negative margins. To set negative margin, first, you set top: 50% and then margin-top to half of the height of the child element. If you have top-padding or border, you may want to adjust for that too, subtracting it from the top-margin. If you don't want to bother with how the height of the element changes because of the padding, just use box-sizing: border-box. Centering horizontally is similar: set some width, left: 50% and margin-left: -(width/2 + padding).

Caveat: beware of possible content spillover if the child block gets taller than the parent one.

Example of centering with negative margins.

Say you have an unformatted Twitter quote about how centering in CSS is hard. I had to choose the width and height that look good on mobile because otherwise, the text overflows its container. You can see the code below and can copy it if you like.

“44 years ago we put a man on the moon, but we still can’t vertically center things in CSS.”

— Juozas Kaziukėnas (@juokaz) July 21, 2013
<div class='relative h5'> <div style='top: 50%; left: 50%; height: 160px; padding: 20px; width: 300px; margin-top: -80px; margin-left: -150px; box-sizing: border-box; position: absolute;'> centered content </div> </div>

Center using CSS Transforms

This technique is similar to NEGATIVE MARGINS, but here you don't need to set the centered block's height. Set position: absolute, top: 50%, left: 50%. And instead of bringing the block back up with margins you use transform: translate(-50%, -50%) for that.

Caveats:

  1. absolute positioning can cause a content overflow;

  2. transform centering will interfere with other transform effects added later;

  3. transform property requires the vendor prefixes;

  4. if the parent container height is an uneven number, the centered block may be rendered blurry. This can be fixed with transform-style: preserve-3d.

Example. Transform and center.

Center a div with the image background.

Pickle Rick.
<div class='relative h5'> <div style='top: 50%; left: 50%; transform: translate(-50%, -50%); transform-style: preserve-3d; position: absolute;'> centered content </div> </div>

Absolute centering

Similar to the previous technique, you are using the absolute position on the element you want to center vertically. A nice advantage of absolute centering technique is that you don't have to set the distance between child and parent elements: child element will be centered automatically.

First, position the element absolutely with position: absolute and add margin: auto, then top: 0 and bottom: 0 to center element vertically and left: 0 with right: 0 to center it horizontally.

Absolute centering example.

Let's take another unformatted Twitter quote.

“You can center anything with absolute positioning, but at a certain cost.”

— Count von Count, July 21, 2013
<div class='relative h5'> <div style='margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0;'> centered content </div> </div>

Flexbox is almost a standard: center almost anything with it both vertically and horizontally

The simplest way to vertically center elements is to use flexbox. It is already supported in many browsers. However, there are old (2009), semi-old (2012) and new specifications which may differ in detail. Still, that doesn’t affect your centering ability too much, you just add necessary prefixes. If you have to support browsers such as IE9 and older, you will still have to look for polyfill-like solutions (Modernizr, for example). Otherwise you just add the display: flex, align-items: center or display: flex, flex-direction: column, justify-content: center.

Centered
with
flexbox

.flex { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; } .flex-row { -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; } .flex-column { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .justify-center { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .items-center { -webkit-box-align: center; -ms-flex-align: center; align-items: center; }
<div class='flex flex-row justify-center items-center'> <div class='flex flex-column justify-center items-center'></div> </div>

Centering with flexbox will work for the most cases when you need to center something.

Caveats:

Watch for container overflow. A parent container using display:flex may not be scrollable and show all content. This problem happens due to the way flexbox centers elements, called "true" centering. Even if the centered element overflows its container, it will remain centered and the parts that overflow are hidden because you cannot scroll to them.

Top part
is not
visible
resize ↘

If you need the scrollable container, you can use one of the following:

1. Margin: auto. Omit the default justify-content: center and/or align-items: center altogether and use margin: auto instead together with overflow value of your choice. This way centers the element both vertically and horizontally just fine.

Overflow
centered
and scrollable
resize ↘

.flex { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; } .margin-auto { margin: auto; }
<div class='flex'> <div class='margin-auto'></div> </div>

2. Safe keyword. This keyword aligns the centered item to 'flex-start' in case if the centered item is larger than its container. It should work by just adding the safe keyword to the justify-content or align-items properties: justify-content: safe center and align-items: safe center. A short solution, but still on the way to browser support.

Probably
not working
in your browser
yet
resize ↘

.flex { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; } .justify-center-safe { justify-content: safe center; } .items-center-safe { align-items: safe center; }
<div class="flex items-center-safe justify-center-safe"> <div></div> </div>

3. Centered element wrapped into a scrollable container. Another way is to just add another wrapper with overflow: auto (or whatever you like) and set height: 8rem, for example. Don't forget to keep the scrollable container scrollable. So if you set display: flex on it - don't center it with justify-content: center or items-center: center, as the centered div will cease to be scrollable again.

Overflow
centered
and scrollable
again
resize ↘
.flex { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; } .justify-center { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .items-center { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .overflow-auto { overflow: auto; } .h4 { height: 8rem; /* example height */ }
<div class="flex items-center justify-center"> <div class="overflow-auto h4"> <div></div> </div> </div>

Centering using CSS Grid

Take your container and set display: grid, place-items: center.

Now the content is centered in all directions. And that's all.

Example of centering with grid.

.grid { display: -ms-grid; display: grid; } .place-center { place-items: center; }
<div class="grid place-center"> <div></div> </div>

Summary

That was an overview of CSS centering techniques available today. Here's a short approximate summary-timeline of the most interesting ones: CSS Centering techniques approzimate timeline

Know other CSS centering techniques? Leave us a comment :)



Ana Makarochkina

After a long journey in cultural studies and management science, Ana realized that code speaks louder than words. Since that time her major areas of focus are Vim, React, and Tachyons. She likes to wr... more about Ana Makarochkina