149

I've searched other questions and, while this problem seems similar to a couple of others, nothing I've seen so far seems to address the issue that I'm having.

I have a div which contains a number of other divs, each of which is floated left. These divs each contain a photo and a caption. All I want is for the group of photos to be centered within the containing div.

As you can see from the code below, I've tried using both overflow:hidden and margin:x auto on the parent divs, and I've also added a clear:both (as suggested in another topic) after the photos. Nothing seems to make a difference.

Thank you. I appreciate any suggestions.

<div style="position: relative; margin: 0 auto; overflow: hidden; text-align: center;">
    <h4>Section Header</h4>

    <div style="margin: 2em auto;">

        <div style="float: left; margin: auto 1.5em;">
            <img src="photo1.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo2.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo3.jpg" /><br />
             Photo Caption
        </div>

        <div style="clear: both; height: 0; overflow: hidden;"> </div>

    </div>

</div>
James A Mohler
  • 11,060
  • 15
  • 46
  • 72
Darren
  • 1,589
  • 2
  • 10
  • 5
  • possible duplicate of [How do I center float elements?](http://stackoverflow.com/questions/4767971/how-do-i-center-float-elements) – TylerH Oct 14 '14 at 18:02
  • @TylerH How come? Just see the date when it was asked. Seems like the question in your link is the real duplicate. – The Pragmatick Feb 28 '15 at 13:40
  • @ThePragmatick Because that one has twice as many views, more answers, more (and more recent) activity, and its wording serves as a better canonical question than this one. – TylerH Feb 28 '15 at 23:33

7 Answers7

274

First, remove the float attribute on the inner divs. Then, put text-align: center on the main outer div. And for the inner divs, use display: inline-block. Might also be wise to give them explicit widths too.


<div style="margin: auto 1.5em; display: inline-block;">
  <img title="Nadia Bjorlin" alt="Nadia Bjorlin" src="headshot.nadia.png"/>
  <br/>
  Nadia Bjorlin
</div>
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Sampson
  • 265,109
  • 74
  • 539
  • 565
  • The main outer div already uses text-align: center and it doesn't seem to do anything. I just added the display: inline-block for each photo and, again, no difference. Just for the sake of argument, I added an explicit width to each photo's div. Absolutely no difference. I'd be curious to see how you just tested it and it works, and I just did it and it didn't make any difference. – Darren Aug 12 '09 at 23:42
  • 6
    @Darren: did you stop floating when you tried? You won't be able to accomplish what you want as long as you're floating /unless/ you set a fixed width on the container of the floats. – Ken Browning Aug 12 '09 at 23:44
  • No, I didn't. I'm still floating the images. For what I want -- the caption centered directly below the image -- I think I have to float the div. But if I float the div, I can't center it in relation to the outer div? – Darren Aug 12 '09 at 23:48
  • 1
    Oh... I'm wrong. Removing the float looks like it accomplishes exactly what I want. I'm not sure that I understand why, but... Thank you very much. – Darren Aug 12 '09 at 23:50
  • 9
    @Darren, notice in my code example I didn't include the floating ;) Read more carefully next time, it'll save you some frustration :) Glad you got it figured out though. Keep up the good work, and welcome to SO. – Sampson Aug 13 '09 at 01:35
  • 1
    Thanks. All I can figure is that I'd been looking at that block of code on my own for two days straight and I just didn't clue into the fact that you omitted the float. Next time I will try to pay closer attention. Again, thank you. – Darren Aug 13 '09 at 03:04
  • 2
    This approach begins to fail when some of the image captions are long enough to line wrap. Any other suggestions? – Grae Kindel Sep 15 '11 at 15:50
  • 3
    Nevermind,found that the varying-line-count captions problem can be fixed with 'vertical-align: top'. =) – Grae Kindel Sep 15 '11 at 15:58
  • Everything I don't know is here on SO. Does that mean I know everything now? Thank you! – ThdK Jun 07 '12 at 17:16
  • @ThdK No. But it does mean you have access to all that you don't know ;) – Sampson Jun 07 '12 at 17:33
  • @Cerin It should work just fine. Here are contrasting examples: http://jsfiddle.net/jonathansampson/y4yhu/ – Sampson Mar 11 '13 at 19:55
  • is there a solution without inline-block? it's not supported in IE7 at least (maybe IE8 too not sure) – Rodolfo Aug 29 '13 at 18:00
  • @Rodolfo, if you are at a point where this works for you in your modern browsers, and you know for a fact that you need to support IE7, then you can take the approach of using a JavaScript framework like jQuery to add special IE7 selectors to your page when JavaScript detects IE7. Or you can attach an IE7 style sheet to your page in conditional comments. Either way you look at it, this is a great answer! – klewis May 05 '14 at 11:05
34

With Flexbox you can easily horizontally (and vertically) center floated children inside a div.

So if you have simple markup like so:

<div class="wpr">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
</div>

with CSS:

.wpr
{
    width: 400px;
    height: 100px;
    background: pink;
    padding: 10px 30px;
}

.wpr span
{
    width: 50px;
    height: 50px;
    background: green;
    float: left; /* **children floated left** */
    margin: 0 5px;
}

(This is the (expected - and undesirable) RESULT)

Now add the following rules to the wrapper:

display: flex;
justify-content: center; /* align horizontal */

and the floated children get aligned center (DEMO)

Just for fun, to get vertical alignment as well just add:

align-items: center; /* align vertical */

DEMO

Danield
  • 121,619
  • 37
  • 226
  • 255
  • still have to check browser-compatibilities, but this seems to be awesome! – low_rents Jun 23 '15 at 08:06
  • You could also use display: inline instead of flex to centering divs. Flex have issues with safari and Opera. – YOU Feb 12 '16 at 20:03
  • inline doesn;t work to me. Problem of this solution is that then the boxes doesn't go to 2nd line if they overflow the width of the div. So you actually turned them into a table... – Pavel Jiri Strnad May 03 '19 at 07:55
11

I accomplished the above using relative positioning and floating to the right.

HTML code:

<div class="clearfix">                          
    <div class="outer-div">
        <div class="inner-div">
            <div class="floating-div">Float 1</div>
            <div class="floating-div">Float 2</div>
            <div class="floating-div">Float 3</div>
        </div>
    </div>
</div>

CSS:

.outer-div { position: relative; float: right; right: 50%; }
.inner-div { position: relative; float: right; right: -50%; }
.floating-div { float: left; border: 1px solid red; margin: 0 1.5em; }

.clearfix:before,
.clearfix:after { content: " "; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }

JSFiddle: http://jsfiddle.net/MJ9yp/

This will work in IE8 and up, but not earlier (surprise, surprise!)

I do not recall the source of this method unfortunately, so I cannot give credit to the original author. If anybody else knows, please post the link!

Kendolein
  • 156
  • 1
  • 4
5

display: inline-block; won't work in any of IE browsers. Here is what I used.

// change the width of #boxContainer to 
// 1-2 pixels higher than total width of the boxes inside:

#boxContainer {         
    width: 800px; 
    height: auto;
    text-align: center;
    margin-left: auto;
    margin-right: auto;
}

#Box{
    width: 240px; 
    height: 90px;
    background-color: #FFF;
    float: left;
    margin-left: 10px;
    margin-right: 10px;
}
Phill Healey
  • 3,084
  • 2
  • 33
  • 67
5

The following solution does not use inline blocks. However, it requires two helper divs:

  1. The content is floated
  2. The inner helper is floated (it stretches as much as the content)
  3. The inner helper is pushed right 50% (its left aligns with center of outer helper)
  4. The content is pulled left 50% (its center aligns with left of inner helper)
  5. The outer helper is set to hide the overflow

.ca-outer {
  overflow: hidden;
  background: #FFC;
}
.ca-inner {
  float: left;
  position: relative;
  left: 50%;
  background: #FDD;
}
.content {
  float: left;
  position: relative;
  left: -50%;
  background: #080;
}
/* examples */
div.content > div {
  float: left;
  margin: 10px;
  width: 100px;
  height: 100px;
  background: #FFF;
}
ul.content {
  padding: 0;
  list-style-type: none;
}
ul.content > li {
  margin: 10px;
  background: #FFF;
}
<div class="ca-outer">
  <div class="ca-inner">
    <div class="content">
      <div>Box 1</div>
      <div>Box 2</div>
      <div>Box 3</div>
    </div>
  </div>
</div>
<hr>
<div class="ca-outer">
  <div class="ca-inner">
    <ul class="content">
      <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
      <li>Nullam efficitur nulla in libero consectetur dictum ac a sem.</li>
      <li>Suspendisse iaculis risus ut dapibus cursus.</li>
    </ul>
  </div>
</div>
Salman A
  • 262,204
  • 82
  • 430
  • 521
3

Solution:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Knowledge is Power</title>
        <script src="js/jquery.js"></script>
        <script type="text/javascript">
        </script>
        <style type="text/css">
            #outer {
                text-align:center;
                width:100%;
                height:200px;
                background:red;
            }
            #inner {
                display:inline-block;
                height:200px;
                background:yellow;
            }
        </style>
    </head>
    <body>
        <div id="outer">
            <div id="inner">Hello, I am Touhid Rahman. The man in Light</div>
        </div>
    </body>
</html>
Touhid Rahman
  • 2,455
  • 21
  • 22
1

In my case, I could not get the answer by @Sampson to work for me, at best I got a single column centered on the page. In the process however, I learned how the float actually works and created this solution. At it's core the fix is very simple but hard to find as evident by this thread which has had more than 146k views at the time of this post without mention.

All that is needed is to total the amount of screen space width that the desired layout will occupy then make the parent the same width and apply margin:auto. That's it!

The elements in the layout will dictate the width and height of the "outer" div. Take each "myFloat" or element's width or height + its borders + its margins and its paddings and add them all together. Then add the other elements together in the same fashion. This will give you the parent width. They can all be somewhat different sizes and you can do this with fewer or more elements.

Ex.(each element has 2 sides so border, margin and padding get multiplied x2)

So an element that has a width of 10px, border 2px, margin 6px, padding 3px would look like this: 10 + 4 + 12 + 6 = 32

Then add all of your element's totaled widths together.

Element 1 = 32
Element 2 = 24
Element 3 = 32
Element 4 = 24

In this example the width for the "outer" div would be 112.

.outer {
  /* floats + margins + borders = 270 */
  max-width: 270px;
  margin: auto;
  height: 80px;
  border: 1px;
  border-style: solid;
}

.myFloat {
    /* 3 floats x 50px = 150px */
    width: 50px;
    /* 6 margins x 10px = 60 */
    margin: 10px;
    /* 6 borders x 10px = 60 */
    border: 10px solid #6B6B6B;
    float: left;
    text-align: center;
    height: 40px;
}
<div class="outer">
  <div class="myFloat">Float 1</div>
  <div class="myFloat">Float 2</div>
  <div class="myFloat">Float 3</div>
</div>
dimmech
  • 827
  • 9
  • 19