Abdu
Abdu

Reputation: 16585

How can I vertically align elements in a div?

I have a div with two images and an h1. All of them need to be vertically aligned within the div, next to each other. One of the images needs to be absolute positioned within the div.

What is the CSS needed for this to work on all common browsers?

<div id="header">
  <img src=".." ></img>
  <h1>testing...</h1>
  <img src="..."></img>
</div>

Upvotes: 1089

Views: 2068384

Answers (30)

WasiF
WasiF

Reputation: 28919

Vertically and horizontally align element

Use either of these. The result would be the same:

  1. Bootstrap 4
  2. CSS3

Enter image description here

1. Bootstrap 4.3+

For vertical alignment: d-flex align-items-center

For horizontal alignment: d-flex justify-content-center

For vertical and horizontal alignment: d-flex align-items-center justify-content-center

.container {
    height: 180px;
    width:100%;
    background-color: blueviolet;
}

.container > div {
  background-color: white;
  padding: 1rem;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
rel="stylesheet"/>

<div class="d-flex align-items-center justify-content-center container">
  <div>I am in Center</div>
</div>

2. CSS 3

.container {
    height: 180px;
    width:100%;
    background-color: blueviolet;
}

.container > div {
  background-color: white;
  padding: 1rem;
}

.center {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="container center">
    <div>I am in Center</div>
</div>

Upvotes: 40

Konrad Rudolph
Konrad Rudolph

Reputation: 546035

Wow, this problem is popular. It's based on a misunderstanding in the vertical-align property. This excellent article explains it:

Understanding vertical-align, or "How (Not) To Vertically Center Content" by Gavin Kistner.

“How to center in CSS” is a great web tool which helps to find the necessary CSS centering attributes for different situations.


In a nutshell (and to prevent link rot):

  • Inline elements (and only inline elements) can be vertically aligned in their context via vertical-align: middle. However, the “context” isn’t the whole parent container height, it’s the height of the text line they’re in. jsfiddle example
  • For block elements, vertical alignment is harder and strongly depends on the specific situation:
    • If the inner element can have a fixed height, you can make its position absolute and specify its height, margin-top and top position. jsfiddle example
    • If the centered element consists of a single line and its parent height is fixed you can simply set the container’s line-height to fill its height. This method is quite versatile in my experience. jsfiddle example
    • … there are more such special cases.

Upvotes: 1154

Hujaakbar
Hujaakbar

Reputation: 1090

Other answers mentioned using Flexbox and Grid. They do work. But if you don't want to use flexbox or grid, there is another elegant solution. As of 2024, align-content is a baseline and works not only in Flexbox, and Grid but also block-level elements as well. mdn link

The CSS align-content property sets the distribution of space between and around content items along a flexbox's cross axis, or a grid or block-level element's block axis.

Basically, you can center elements of a block-level container with one line of code:

align-content: center;

div#header{
  border: 3px solid black;
  height: 400px;

  align-content: center;
}
<div id="header">
  <img alt='some image' src=".." ></img>
  <h1>testing...</h1>
  <img alt='some image' src="..."></img>
</div>

Upvotes: 0

Igor Alemasow
Igor Alemasow

Reputation: 4899

This day has come!

align-content property for block layouts can be used for aligning.

#outer {
  align-content: center;
  height: 100px;
  border: 1px solid grey;
}
<div id="outer">
   <div id="inner">CSS is awesome</div>
</div>

Browser Support:

  • Chrome 123
  • Edge 123
  • Firefox 125
  • Safari 17.4

Upvotes: 6

Maxim Rysevets
Maxim Rysevets

Reputation: 155

I tried to do it using CSS flex but it truncates the object if it goes beyond the block (with "overflow: auto").

Through experimentation, I discovered that it is very easy to center any object (line or block) if you use Grid.

I really liked the solution, so I implemented it in the CMS Effcore.

Here is a code example:

<head>
    <style>
        [data-id^='example-'] {
          max-width: 800px;
          height: 200px;
          margin: 20px auto;
          background: gray;
        }
        [data-id^='example-'] img {
          width: 50px;
          height: 50px;
          border: 1px solid black;
          background: gray;
        }
    </style>
</head>
<body>
    <div data-id="example-1">
        <img src="gallery/pictures/thumbnail-01.png">
    </div>
    <div data-id="example-2">
        <img src="gallery/pictures/thumbnail-01.png">
    </div>
    <div data-id="example-3">
        <img src="gallery/pictures/thumbnail-01.png">
    </div>
</body>
</html>

Example via Grid:

/*
┌─────┬───────────────────────┬─────┐
│ 1fr │          1fr          │ 1fr │
├─────┼───────────────────────┼─────┤
│     │  ▲                    │     │
│     │ ◀┼──────────────────▶ │     │
│ 1fr │  │ 1px|max-content    │ 1fr │
│     │  │                    │     │
│     │  ▼                    │     │
├─────┼───────────────────────┼─────┤
│ 1fr │          1fr          │ 1fr │
└─────┴───────────────────────┴─────┘
*/

[data-id='example-1'] {
  display: grid;
  grid-template-columns: 1fr minmax(1px, max-content) 1fr;
  grid-template-rows   : 1fr minmax(1px, max-content) 1fr;
}

[data-id='example-1'] img {
  grid-column-start: 2;
  grid-row-start:    2;
}

Example via "flex".

[data-id='example-2'] {
  display: flex;
  align-items: center;
}

[data-id='example-2'] img {
  margin: 0 auto;
}

Example via "vertical-align".

[data-id='example-3'] {
  text-align: center;
  white-space: nowrap;
}

[data-id='example-3']:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

[data-id='example-3'] img {
  vertical-align: middle;
}

A live code example can be found here: https://developer.mozilla.org/ru/play?id=AE9iTZBMsHnSmr4lfRPvmQU3p6DMFO4uGxZY%2BM7ABDgHuUotnvJdG5VISHO5%2BkYdb7YGTMQtKr2HlhGc

Upvotes: 0

akhtarvahid
akhtarvahid

Reputation: 9779

Four ways to to align child(div) in center.

  • Absolute positioning method
  • Flexbox method
  • Transform/translate method
  • CSS grid method

Browser support for CSS grid

Enter image description here

Demo

/* Absolute Positioning Method */
.parent1 {
  background: darkcyan;
   width: 150px;
   height: 150px;
   position: relative;
}
.child1 {
  background: white;
  height: 30px;
  width: 30px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -15px;
}

/* Flexbox Method */
.parent2 {
  display: flex;
  justify-content: center;
  align-items: center;
  background: darkcyan;
  width: 150px;
  height: 150px;
}
.child2 {
  background: white;
  height: 30px;
  width: 30px;
}

/* Transform/Translate Method */
.parent3 {
  position: relative;
  width: 150px;
  height: 150px;
  background: darkcyan;
}
.child3 {
  background: white;
  height: 30px;
  width: 30px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* CSS grid */
.parent4, .parent5 {
  position: relative;
  width: 150px;
  height: 150px;
  background: darkcyan;
  display: grid;
  place-items: center;
}
.child4, .child5 {
  background: white;
  height: 30px;
  width: 30px;
}
.parent5 {
  display: grid;
  justify-items: centre;
  align-content: centre;
}
<div class="parent1">
  <div class="child1"></div>
</div>
<hr />

<div class="parent2">
  <div class="child2"></div>
</div>
<hr />

<div class="parent3">
  <div class="child3"></div>
</div>
<hr />

<div class="parent4">
  <div class="child4"></div>
</div>
<hr />

<div class="parent5">
  <div class="child5"></div>
</div>

Upvotes: 18

Arsh
Arsh

Reputation: 21

I have been using the following solution (with no positioning and no line height) for over a year. It works with Internet Explorer 7 and Internet Explorer 8 as well.

<style>
.outer {
    font-size: 0;
    width: 400px;
    height: 400px;
    background: orange;
    text-align: center;
    display: inline-block;
}

.outer .emptyDiv {
    height: 100%;
    background: orange;
    visibility: collapse;
}

.outer .inner {
    padding: 10px;
    background: red;
    font: bold 12px Arial;
}

.verticalCenter {
    display: inline-block;
    *display: inline;
    zoom: 1;
    vertical-align: middle;
}
</style>

<div class="outer">
    <div class="emptyDiv verticalCenter"></div>
    <div class="inner verticalCenter">
        <p>Line 1</p>
        <p>Line 2</p>
    </div>
</div>

Upvotes: 0

Shadoweb
Shadoweb

Reputation: 6306

Almost all methods needs to specify the height, but often we don't have any heights.

So here is a CSS 3 three-line trick that doesn't require to know the height.

.element {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

It's supported even in Internet Explorer 9.

with its vendor prefixes:

.element {
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}

Source: Vertical align anything with just 3 lines of CSS

Upvotes: 17

user1688793
user1688793

Reputation:

Here is just another (responsive) approach:

html,
    body {
        height: 100%;
    }
    body {
        margin: 0;
    }

    .table {
        display: table;
        width:  auto;
        table-layout:auto;
        height: 100%;
    }
        .table:nth-child(even) {
            background: #a9edc3;
        }
        .table:nth-child(odd) {
            background: #eda9ce;
        }

    .tr {
        display: table-row;
    }
    .td {
        display: table-cell;
        width: 50%;
        vertical-align: middle;
    }

http://jsfiddle.net/herrfischerhamburg/JcVxz/

Upvotes: -4

abernier
abernier

Reputation: 28218

A technique from a friend of mine:

div:before {content:" "; display:inline-block; height:100%; vertical-align:middle;}
div p {display:inline-block;}
<div style="height:100px; border:1px solid;">
    <p style="border:1px dotted;">I'm vertically centered.</p>
</div>

Demo here.

Upvotes: 29

Mike Tunnicliffe
Mike Tunnicliffe

Reputation: 10772

By default h1 is a block element and will render on the line after the first img, and will cause the second img to appear on the line following the block.

To stop this from occurring you can set the h1 to have inline flow behaviour:

#header > h1 { display: inline; }

As for absolutely positioning the img inside the div, you need to set the containing div to have a "known size" before this will work properly. In my experience, you also need to change the position attribute away from the default - position: relative works for me:

#header { position: relative; width: 20em; height: 20em; }
#img-for-abs-positioning { position: absolute; top: 0; left: 0; }

If you can get that to work, you might want to try progressively removing the height, width, position attributes from div.header to get the minimal required attributes to get the effect you want.

UPDATE:

Here is a complete example that works on Firefox 3:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
        <head>
            <title>Example of vertical positioning inside a div</title>
            <style type="text/css">
                #header > h1 { display: inline; }
                #header { border: solid 1px red; 
                          position: relative; }
                #img-for-abs-positioning { position: absolute;
                                           bottom: -1em; right: 2em; }
            </style>
        </head>
    
        <body>
            <div id="header">
                <img src="#" alt="Image 1" width="40" height="40" />
                <h1>Header</h1>
                <img src="#" alt="Image 2" width="40" height="40" 
                     id="img-for-abs-positioning" />
            </div>
        </body>
    </html>

Upvotes: 3

user2346571
user2346571

Reputation: 1407

I used this very simple code:

div.ext-box { display: table; width:100%;}
div.int-box { display: table-cell; vertical-align: middle; }
<div class="ext-box">
    <div class="int-box">
        <h2>Some txt</h2>
        <p>bla bla bla</p>
    </div>
</div>

Obviously, whether you use a .class or an #id, the result won't change.

Upvotes: 139

E. Serrano
E. Serrano

Reputation: 5024

Now that Flexbox support is increasing, this CSS applied to the containing element would vertically center all contained items (except for those items that specify the alignment themselves, e.g. align-self:start)

.container {
    display: flex;
    align-items: center;
}

Use the prefixed version if you also need to target Internet Explorer 10, and older (< 4.4 (KitKat)) Android browsers:

.container {
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -ms-flex-align: center;
    -webkit-align-items: center;
    -webkit-box-align: center;
    align-items: center;
}

Upvotes: 374

MD TAREQ HASSAN
MD TAREQ HASSAN

Reputation: 1276

Using only a Bootstrap class:

  • div: class="container d-flex"
  • element inside div: class="m-auto"

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css" crossorigin="anonymous">

<div class="container d-flex mt-5" style="height:110px; background-color: #333;">
  <h2 class="m-auto"><a href="https://hovermind.com/">H➲VER➾M⇡ND</a></h2>
</div>

Upvotes: 3

Dennis Don
Dennis Don

Reputation: 287

Using display flex, first you need to wrap the container of the item that you want to align:

<div class="outdiv">
    <div class="indiv">
        <span>test1</span>
        <span>test2</span>
    </div>
</div>

Then apply the following CSS content to wrap div or outdiv in my example:

.outdiv {
    display: flex;
    justify-content: center;
    align-items: center;
}

Upvotes: 7

Shiv
Shiv

Reputation: 3285

I have found a new workaround to vertically align multiple text-lines in a div using CSS 3 (and I am also using bootstrap v3 grid system to beautify the UI), which is as below:

.immediate-parent-of-text-containing-div {
    height: 50px;         /* Or any fixed height that suits you. */
}

.text-containing-div {
    display: inline-grid;
    align-items: center;
    text-align: center;
    height: 100%;
}

As per my understanding, the immediate parent of text containing element must have some height.

Upvotes: 4

Dashrath
Dashrath

Reputation: 2189

We may use a CSS function calculation to calculate the size of the element and then position the child element accordingly.

Example HTML:

<div class="box">
    <span><a href="#">Some Text</a></span>
</div>

And CSS:

.box {
    display: block;
    background: #60D3E8;
    position: relative;
    width: 300px;
    height: 200px;
    text-align: center;
}

.box span {
    font: bold 20px/20px 'source code pro', sans-serif;
    position: absolute;
    left: 0;
    right: 0;
    top: calc(50% - 10px);
}

a {
    color: white;
    text-decoration: none;
}

Demo created here: https://jsfiddle.net/xnjq1t22/

This solution works well with responsive div height and width as well.

Note: The calc function is not tested for compatiblity with old browsers.

Upvotes: 3

Henk-Martijn
Henk-Martijn

Reputation: 2024

Using CSS to vertical center, you can let the outer containers act like a table, and the content as a table cell. In this format your objects will stay centered. :)

I nested multiple objects in JSFiddle for an example, but the core idea is like this:

HTML

<div class="circle">
  <div class="content">
    Some text
  </div>
</div>

CSS

.circle {
  /* Act as a table so we can center vertically its child */
  display: table;
  /* Set dimensions */
  height: 200px;
  width: 200px;
  /* Horizontal center text */
  text-align: center;
  /* Create a red circle */
  border-radius: 100%;
  background: red;
}

.content {
  /* Act as a table cell */
  display: table-cell;
  /* And now we can vertically center! */
  vertical-align: middle;
  /* Some basic markup */
  font-size: 30px;
  font-weight: bold;
  color: white;
}

The multiple objects example:

HTML

<div class="container">
  <div class="content">

    <div class="centerhoriz">

      <div class="circle">
        <div class="content">
          Some text
        </div><!-- content -->
      </div><!-- circle -->

      <div class="square">
        <div class="content">
          <div id="smallcircle"></div>
        </div><!-- content -->
      </div><!-- square -->

    </div><!-- center-horiz -->

  </div><!-- content -->
</div><!-- container -->

CSS

.container {
  display: table;
  height: 500px;
  width: 300px;
  text-align: center;
  background: lightblue;
}

.centerhoriz {
  display: inline-block;
}

.circle {
  display: table;
  height: 200px;
  width: 200px;
  text-align: center;
  background: red;
  border-radius: 100%;
  margin: 10px;
}

.square {
  display: table;
  height: 200px;
  width: 200px;
  text-align: center;
  background: blue;
  margin: 10px;
}

.content {
  display: table-cell;
  vertical-align: middle;
  font-size: 30px;
  font-weight: bold;
  color: white;
}

#smallcircle {
  display: inline-block;
  height: 50px;
  width: 50px;
  background: green;
  border-radius: 100%;
}

Result

Result

https://jsfiddle.net/martjemeyer/ybs032uc/1/

Upvotes: 5

joan16v
joan16v

Reputation: 5139

My trick is to put a table inside the div with one row and one column, set 100% of width and height, and the property vertical-align:middle:

<div>

    <table style="width:100%; height:100%;">
        <tr>
            <td style="vertical-align:middle;">
                BUTTON TEXT
            </td>
        </tr>
    </table>

</div>

Fiddle: http://jsfiddle.net/joan16v/sbqjnn9q/

Upvotes: 12

SoniCoder
SoniCoder

Reputation: 4174

To position block elements to the center (works in Internet Explorer 9 and above), it needs a wrapper div:

.vcontainer {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
}

Upvotes: 25

danigonlinea
danigonlinea

Reputation: 1113

This is my personal solution for an i element inside a div.

JSFiddle Example

HTML

<div class="circle">
    <i class="fa fa-plus icon">
</i></div>

CSS

.circle {
   border-radius: 50%;
   color: blue;
   background-color: red;
   height:100px;
   width:100px;
   text-align: center;
   line-height: 100px;
}

.icon {
  font-size: 50px;
  vertical-align: middle;
}

Upvotes: 0

Anita Mandal
Anita Mandal

Reputation: 393

Use this formula, and it will work always without cracks:

#outer {height: 400px; overflow: hidden; position: relative;}
#outer[id] {display: table; position: static;}

#middle {position: absolute; top: 50%;} /* For explorer only*/
#middle[id] {display: table-cell; vertical-align: middle; width: 100%;}

#inner {position: relative; top: -50%} /* For explorer only */
/* Optional: #inner[id] {position: static;} */
<div id="outer">
  <div id="middle">
    <div id="inner">
      any text
      any height
      any content, for example generated from DB
      everything is vertically centered
    </div>
  </div>
</div>

Upvotes: 17

 .outer {
   display: flex;
   align-items: center; 
   justify-content: center;
 }

Upvotes: 114

Romain
Romain

Reputation: 1105

It worked for me:

.vcontainer {
    min-height: 10em;
    display: table-cell;
    vertical-align: middle;
}

Upvotes: 56

Stephen
Stephen

Reputation: 8178

My new favorite way to do it is with a CSS grid:

/* technique */

.wrapper {
  display: inline-grid;
  grid-auto-flow: column;
  align-items: center;
  justify-content: center;
}

/* visual emphasis */

.wrapper {
  border: 1px solid red;
  height: 180px;
  width: 400px;
}

img {
  width: 100px;
  height: 80px;
  background: #fafafa;
}

img:nth-child(2) {
  height: 120px;
}
<div class="wrapper">
  <img src="https://source.unsplash.com/random/100x80/?bear">
  <img src="https://source.unsplash.com/random/100x120/?lion">
  <img src="https://source.unsplash.com/random/100x80/?tiger">
</div>

Upvotes: 2

BernieSF
BernieSF

Reputation: 1828

For me, it worked this way:

<div style="width:70px; height:68px; float:right; display: table-cell; line-height: 68px">
    <a href="javascript:void(0)" style="margin-left: 4px; line-height: 2" class="btn btn-primary">Login</a>
</div>

The "a" element converted to a button, using Bootstrap classes, and it is now vertically centered inside an outer "div".

Upvotes: 0

pr0gg3r
pr0gg3r

Reputation: 4443

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
    <head>
        <style type="text/css">
            #style_center { position:relative; top:50%; left:50%; }
            #style_center_absolute { position:absolute; top:50px; left:50px; }
            <!--#style_center { position:relative; top:50%; left:50%; height:50px; margin-top:-25px; }-->
        </style>
    </head>

    <body>
        <div style="height:200px; width:200px; background:#00FF00">
            <div id="style_center">+</div>
        </div>
    </body>
</html>

Upvotes: -3

Joel Moses
Joel Moses

Reputation: 27

Just use a one-cell table inside the div! Just set the cell and table height and with to 100% and you can use the vertical-align.

A one-cell table inside the div handles the vertical-align and is backward compatible back to the Stone Age!

Upvotes: 1

Joel Moses
Joel Moses

Reputation: 27

Just this:

<div>
    <table style="width: 100%; height: 100%">
        <tr>
            <td style="width: 100%; height: 100%; vertical-align: middle;">
               What ever you want vertically-aligned
            </td>
        </tr>
    </table>
</div>

A one-cell table inside the div handles the vertical-align and is backward compatible back to the Stone Age!

Upvotes: -3

dimarzionist
dimarzionist

Reputation: 18687

<div id="header" style="display: table-cell; vertical-align:middle;">

...

or CSS

.someClass
{
   display: table-cell;
   vertical-align:middle;
}

Browser Coverage

Upvotes: -8

Related Questions