55

I'm having issues centering icons (both vertically and horizontally) in a parent div. I have many parent divs on my page that are different sizes, so I want to be able to proportionally place icons in the center of each parent div. Here's a JSFiddle of the problem:

JsFiddle

HTML

<div class="img_container">
  <i class="icon-play-circle"></i>
</div>
<br>
<div class="img_container2">
  <i class="icon-play-circle"></i>
</div>

CSS

.img_container{
    width:100px;
    height:100px;
    position:relative;
    background:red;
}

.img_container2{
    width:100px;
    height:50px;
    position:relative;
    background:blue;
}

.icon-play-circle{
    position:absolute;
    top:45%;
    left:45%;
    color: white;
}
MrMaavin
  • 1,611
  • 2
  • 19
  • 30
scientiffic
  • 9,045
  • 18
  • 76
  • 149

3 Answers3

59

Since they are already inline-block child elements, you can set text-align:center on the parent without having to set a width or margin:0px auto on the child. Meaning it will work for dynamically generated content with varying widths.

.img_container, .img_container2 {
    text-align: center;
}

This will center the child within both div containers.

UPDATE:

For vertical centering, you can use the calc() function assuming the height of the icon is known.

.img_container > i, .img_container2 > i {
    position:relative;
    top: calc(50% - 10px); /* 50% - 3/4 of icon height */
}

jsFiddle demo - it works.

For what it's worth - you can also use vertical-align:middle assuming display:table-cell is set on the parent.

Matt
  • 74,352
  • 26
  • 153
  • 180
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • doesn't this only center the child horizontally (and not vertically?) – scientiffic Oct 01 '13 at 19:32
  • @scientiffic Yea, this will only center horizontally.. You didn't say that you wanted it vertically, do you what it that way also? – Josh Crozier Oct 01 '13 at 19:33
  • 1
    yes, sorry that I didn't clarify. the main issue is having it center vertically. – scientiffic Oct 01 '13 at 19:34
  • @scientiffic Alright, give me a few mins. I'll update my answer. – Josh Crozier Oct 01 '13 at 19:35
  • vertical-align: middle but also line-height: 100px? – Otis Oct 01 '13 at 19:39
  • @scientiffic Like this? http://jsfiddle.net/aHUtM/1/ – Josh Crozier Oct 01 '13 at 19:42
  • Those don't look centered; they look like the image is beginning at at the center line. If it's not important that the icon be an image and the DIV it's in has a fixed size, you could set the background-image to be the picture with background-repeat: no-repeat and background-position: center center. – Otis Oct 01 '13 at 19:44
  • @Otis This is what i'm getting: http://i.stack.imgur.com/ulmD8.png – Josh Crozier Oct 01 '13 at 19:48
  • When I load your image (or a screen-shot of the jsfiddle) into Paint.NET, I'm counting 100px above the circle and 88px below the circle which isn't centered; the circle takes up the other 12px. Try: http://jsfiddle.net/aHUtM/2/ – Otis Oct 01 '13 at 19:56
  • @JoshC your vertical centering solution doesn't work in this context. He specifically said there will be many different div heights to account for (which means your code is an approximation of vertical centering at best) and furthermore you are assuming that each div has fixed and known height which is not a safe assumption. – Ennui Oct 01 '13 at 20:00
  • thanks again for your help. it's almost working, but when I adjust the size of the divs, it isn't centered vertically: http://jsfiddle.net/aHUtM/4/ – scientiffic Oct 01 '13 at 20:03
  • @Ennui If you read through the comments, you will notice that he didn't originally state he wanted it done both vertically and horizontally. I posted a solution for horizontal centering. He later updated the question to include both. At the time I posted this solution it worked in the context assuming that the content was of differing widths and not of varying heights. – Josh Crozier Oct 01 '13 at 20:05
  • 1
    @scientiffic I updated it to include calc() http://jsfiddle.net/aHUtM/6/ assuming the height of the icon is known. – Josh Crozier Oct 01 '13 at 20:07
  • 1
    thanks, Josh, I didn't know about calc! it works great. can you add it as an answer, and I'll mark it was the correct one? – scientiffic Oct 01 '13 at 20:12
  • @scientiffic I updated it – Josh Crozier Oct 01 '13 at 20:13
  • @scientiffic or you can mark my solution which is less verbose and works in all situations without knowing height or width of the parent container OR the element being centered ;) – Ennui Oct 01 '13 at 20:13
  • @JoshC I left the icon wrapped because that's how his markup was to begin with! – Ennui Oct 01 '13 at 20:15
  • 1
    I guess this is the "bestest" solution. :D – Michael Nov 10 '14 at 14:24
22

Here is a way to center content both vertically and horizontally in any situation, which is useful when you do not know the width or height or both:

CSS

#container {
    display: table;
    width: 300px; /* not required, just for example */
    height: 400px; /* not required, just for example */
}

#update {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

HTML

<div id="container">
    <a id="update" href="#">
        <i class="icon-refresh"></i>
    </a>
</div>

JSFiddle

Note that the width and height values are just for demonstration here, you can change them to anything you want (or remove them entirely) and it will still work because the vertical centering here is a product of the way the table-cell display property works.

Sofía
  • 784
  • 10
  • 24
Ennui
  • 10,102
  • 3
  • 35
  • 42
7

Horizontal centering is as easy as:

text-align: center

Vertical centering when the container is a known height:

height: 100px;
line-height: 100px;
vertical-align: middle

Vertical centering when the container isn't a known height AND you can set the image in the background:

background: url(someimage) no-repeat center center;
Otis
  • 992
  • 3
  • 12
  • 22