By James


2011-12-30 22:45:43 8 Comments

I have a bunch of inline-block elements over several lines which I'd like to center horizontally. The inline-block elements all have the same fixed size, but I'd like the centering to be able to handle page resizing and adding or removing elements.

I've stripped down the html/css and removed the attempt at centering for clarity. It's at http://jsfiddle.net/fe25H/1/

If you resize the results window so that the third inline-block element drops down, the container fills the width and we get this:

-----------------BODY------------------
|                                     |
||-------------CONTAINER-------------||
||-INLINEBLOCK---INLINEBLOCK--       ||
|||____________||____________|       ||
||-INLINEBLOCK--                     ||
|||____________|                     ||
||___________________________________||
|_____________________________________|

rather than this:

-----------------BODY------------------
|                                     |
|   |----------CONTAINER---------|    |
|   |-INLINEBLOCK---INLINEBLOCK--|    |
|   ||____________||____________||    |
|   |-INLINEBLOCK--              |    |
|   ||____________|              |    |
|   |____________________________|    |
|_____________________________________|

edit based on ptriek's answer regarding a JavaScript solution:

Ptriek's code was a useful starting point; it works for the specific case, but not the general one. I've mostly rewritten it to be more flexible (see http://jsfiddle.net/fe25H/5/).

3 comments

@Sam Hughes 2017-01-19 17:26:50

The issue stated is, as far as my CSS knowledge will take me, not perfectly solvable with purely CSS.

Mike M. Lin's answer is a very ingenious method, I love the creativity, but there are some errors with it that I can expand on.

NOTE: If anyone finds out the general solution, please let us know, since no-body has done it. Etsy, Amazon, Redbubble, can't see this being achieved anywhere...


1)

You do not need "2 minus the length of the array of div items", this could get computationally expensive for large n of items. Rather, as an approximate rule, you need enough placeholder "blocks" to create a new line in the container. In fact, the number of placeholders is (in pseudocode):

let n = number of block items to display
let n_max = number of block items that fit into one row
let n_ph = number of "placeholder" block items

/*if number of items exceeds max number for a row (starts a new line), then 
 you'll need to start another line with n_max - 1 placeholders*/
if n >= n_max then
    n_ph = n_max - 1
end if

//you don't need any placeholders if number of items fills all rows completely
if n % n_max == 0 then
    n_ph = 0
end if

Notice that I have omitted the case when n < n_max. That is difficult, and you will have to play around with your n_ph values for when n < n_max. If you need n_ph to work for different window sizes, I would consider adding a window width observer and adding or taking away a placeholder for your "responsive" width bands. It is a pain, but you will likely either not have n < n_max ever, or, your n_max is small and it's not a pain to "manually taylor" n_ph for the responsive bands.

2)

You don't need the container to be inline-block. It works with or without it I have found.

@ptriek 2011-12-31 00:16:00

After thinking a bit about it, I agree with Wex' comment above.

So I fiddled a JavaScript solution (jQuery) - I'm not an expert on this, so the code might be improved - but I guess it does exactly what you need:

var resizeContainer = function () {
    var w_window = $(window).width();
    var w_block = $('.inlineblock').width();
    if (w_window < w_block * 3 && w_window >= w_block * 2) {
        $('.container').width(w_block * 2);
    } else if (w_window < w_block * 2) {
        $('.container').width(w_block);
    }  else {
        $('.container').width(w_block * 3);
    } 
};


$(document).ready(resizeContainer);
$(window).resize(resizeContainer);
body {
    text-align:center;
}
.container {
    display: inline-block;
    background-color: #aaa;
    text-align:left;
}
.inlineblock {
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: #eee;
}
<div class='container'>
    <div class='inlineblock'></div>
    <div class='inlineblock'></div>
    <div class='inlineblock'></div>
</div>

http://jsfiddle.net/ptriek/fe25H/4/

@James 2011-12-31 12:15:16

Thanks, see the edit to the original question where I've improved the JS.

@Mike M. Lin 2015-03-24 17:19:58

You can add invisible placeholders to the end of your inline blocks. That will left-align the last row.

http://jsfiddle.net/aakt65x4/

However, if you don't fill up the first row, the entire thing will appear left-aligned.

HTML:

<!--
  Centers a group of boxes that wrap to the width of its container.
  Also left-aligns them inside the container.
  Issue: Does not center group if there aren't enough boxes to fill
  the first row.
  -->
<div class="container">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>

    <!--
      How many placeholders do you need?
      At least the number of blocks minus two.
      -->
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
    <div class="placeholder"></div>
</div>

CSS:

body {
    text-align: center;     /* center a max-width container */
    font-size: 0;           /* remove spaces between blocks */
}
.container {                /* you don't need this */
    background-color: #eee; /* so you can see what's happening */
    max-width: 960px;       /* to demonstrate the centering of a max-width container */
    display: inline-block;  /* center the max-width container */
    text-align: center;     /* center the group of blocks */
}
.block {
    display: inline-block;  /* left-align within the group */
    background-color: red;  /* so you can see what's happening */
    height: 100px;
    width: 100px;
    margin: 10px;
}
.placeholder {
    display: inline-block;  /* add to the line of blocks */
    width: 120px;           /* width + margin of a block */
}

Related Questions

Sponsored Content

34 Answered Questions

[SOLVED] How to center absolutely positioned element in div?

23 Answered Questions

[SOLVED] CSS center text (horizontally and vertically) inside a div block

  • 2011-04-18 13:22:47
  • Satch3000
  • 1712407 View
  • 798 Score
  • 23 Answer
  • Tags:   html css

25 Answered Questions

[SOLVED] How to center a "position: absolute" element

5 Answered Questions

[SOLVED] What is the difference between display: inline and display: inline-block?

  • 2012-01-23 09:22:22
  • Logesh Paul
  • 183776 View
  • 588 Score
  • 5 Answer
  • Tags:   css display

39 Answered Questions

[SOLVED] How do I remove the space between inline-block elements?

  • 2011-02-22 12:41:14
  • ┼áime Vidas
  • 261721 View
  • 1020 Score
  • 39 Answer
  • Tags:   html css

9 Answered Questions

[SOLVED] CSS to line break before/after a particular `inline-block` item

  • 2011-01-05 21:16:31
  • Phrogz
  • 275226 View
  • 202 Score
  • 9 Answer
  • Tags:   html css

5 Answered Questions

[SOLVED] Center grid of inline-blocks within container

  • 2013-05-26 13:23:58
  • Paul Repin
  • 7926 View
  • 2 Score
  • 5 Answer
  • Tags:   css

6 Answered Questions

[SOLVED] Centering element inside an element (jQuery)

4 Answered Questions

[SOLVED] Have block level element fill 100% width of overflow-x: scroll container

  • 2014-06-03 15:27:00
  • Valera
  • 2179 View
  • 4 Score
  • 4 Answer
  • Tags:   html css

Sponsored Content