3

I have multiple smaller fix sized div floated inside a container div. I want them to be equally spaced so that the whole block gives the impression of being center aligned.

Right now they are aligned to the left (this is how float works, I know). I understand this is not readily possible, but just want some hacks so that I can achieve the same.

enter image description here

One way to do that is to calculate the necessary width (let say I need 3 divs per row, each 100px wide with 10px margin. So total width of container should be 100*3+60) and apply that width to the container div and set margin auto.

#container {
    width: 360px;
    margin: 0px auto;
}
.items { /* these are smaller divs */
    width: 100px;
    margin: 10px;
    float: left;
}

enter image description here

But this won't look nice with different screen size unless I specifically set width for different medias.

Another way is to use the flex display.

#container {
    display: flex;
    flex-wrap:wrap;
    justify-content: space-between;
}
.items { /* these are smaller divs */
    flex: 0 0 auto;
    width: 100px;
    margin: 10px;
}

It almost served my purpose, but the issue is when you have more than one divs in the bottom row, it just put the second div at the rightmost side, rather than aligning under second column (again this is expected behavior I know, not any issue).

So, are there any tricks/hacks for what I want to achieve?

enter image description here

UPDATE (in response to the duplicate reporting): The solution of the other question (that is reported as same as this question) uses fixed container width whereas I mentioned above that I don't want to fix container width. So that solution was not the one I am looking for.

The solution that worked perfectly is mentioned by Josh below, with only change of justify-content: space-around so that contents remain centered even when the window is narrowed.

abdfahim
  • 2,523
  • 10
  • 35
  • 71
  • inner block can of only fixed size or it can be in percentile ? – schoolcoder Nov 22 '15 at 02:38
  • Aside from the issue with the bottom row in flex, you also have this: when the screen size narrows, the items are no longer centered. – Michael Benjamin Nov 22 '15 at 12:56
  • 2
    Possible duplicate of [Center flex container but align left flex items](http://stackoverflow.com/questions/32802202/center-flex-container-but-align-left-flex-items) – Michael Benjamin Nov 22 '15 at 13:11
  • 1
    The solution provided here by Josh Crozier is perfect, unique and doesn't require to specifically set the width of container for different media size, like you proposed in your solution in the link you provided. So for me, that solution doesn't work (I guess I have mentioned in the question that I don't want to fix the width of container). – abdfahim Nov 23 '15 at 00:16
  • 1
    "when the screen size narrows, the items are no longer centered" .... it does, if you just change the justify-content: space-around, with Josh's solution below. – abdfahim Nov 23 '15 at 00:19
  • I'm glad you got your answer and the question is resolved. But just for the record, the elements are clearly not centered on narrower screens. For the most clear illustration of this, narrow the browser window on Josh's demo to a single column. That's not centered; that's left-aligned. – Michael Benjamin Nov 23 '15 at 15:02
  • 1
    Have you changed justify-content: space-around in container? Because for me it is perfectly centered with single column. Check JSFiddle: http://jsfiddle.net/abdfahim/yyr1w5kq/8/ ........ Also here is the image shot for 4 cases (1 to 4 column): http://imgur.com/kPRd5Vv – abdfahim Nov 23 '15 at 21:20
  • 1
    Yeah, everything looks good now. Don't know why it didn't appear centered when I tested earlier. I've upvoted the question and answer. – Michael Benjamin Nov 28 '15 at 01:12

3 Answers3

3

So, are there any tricks/hacks for what I want to achieve?

This is definitely a hack, but it seems to work. You can add some empty flexbox items with a height of 0 to serve as placeholders. In doing so, the flexbox item placement will be calculated as expected, because the empty flexbox item's width will be accounted for and fill the space.

The minimum number of empty flexbox items should be equal to the maximum number of flexbox items in a row minus one. Of course, you can always add more.. just in case.

In the example below, I used the :empty pseudo class to select the empty placeholder flexbox items.

Updated Example

The relevant CSS:

.items:empty {
  visibility: hidden;
  height: 0;
  width: 100px;
  margin: 0 10px 0;
}

Full HTML/CSS:

#container {
  background-color: #000;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  margin: 25px auto;
}
.items {
  flex: 0 0 auto;
  width: 100px;
  margin: 10px;
}
#item1 {
  background-color: #F00;
}
#item2 {
  background-color: #0F0;
}
#item3 {
  background-color: #00F;
}
#item4 {
  background-color: #ABC;
}
#item5 {
  background-color: #A00;
}
#item6 {
  background-color: #6AF;
}
#item7 {
  background-color: #07A;
}
#item8 {
  background-color: #A79;
}
#item9 {
  background-color: #AF4;
}
#item10 {
  background-color: #FF4;
}
.items:empty {
  visibility: hidden;
  height: 0;
  width: 100px;
  margin: 10px;
  margin-top: 0;
  margin-bottom: 0;
}
<div id="container">
    <div id="item1" class="items">a</div>
    <div id="item2" class="items">b</div>
    <div id="item3" class="items">c</div>
    <div id="item4" class="items">c</div>
    <div id="item5" class="items">c</div>
    <div id="item6" class="items">c</div>
    <div id="item7" class="items">c</div>
    <div id="item8" class="items">c</div>
    <div id="item9" class="items">c</div>
    <div id="item10" class="items">c</div>
    <div class="items"></div><div class="items"></div><div class="items"></div><div class="items"></div><div class="items"></div><div class="items"></div><div class="items"></div><div class="items"></div><div class="items"></div>
</div>
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
0

To center a div like that you going to need it in a container like this. So I added a class holder with a max-width and margin: 0 auto so it's centered inside the container. Fiddle

So items have to

C.Schubert
  • 2,034
  • 16
  • 20
  • 1
    that'd cause the divs in the last row be aligned absolute center (not aligned with the divs of other rows). http://jsfiddle.net/abdfahim/yyr1w5kq/5/ – abdfahim Nov 22 '15 at 02:00
  • 1
    this will work only for a certain browser width. Try to drag fiddle display portion to reduce the width and display 3 items each row. You'll see the divs are aligned left. – abdfahim Nov 22 '15 at 02:19
0

I hope you can use JQuery.

You can set:

#container {
    width: 100%;
}

.items {
    float: left;
    width: 100px;
    margin: 10px 0px;
}

After load and resize page you can execute a function that calculate and set margin

function setMargin() {
    cWidth = $('#container').width();
    iWidth = $('.items').width();

    totalItems = $('.items').length;
    itemsPerRow = parseInt(cWidth / iWidth);

    if(totalItems < itemsPerRow) {
        space = cWidth - iWidth * totalItems;
        margin = space/(totalItems+1);
    } else {
        space = cWidth - iWidth * itemsPerRow;
        margin = space/(itemsPerRow+1);
    }

    $(".items").css("margin-left", margin+"px");

}
Lipsyor
  • 428
  • 1
  • 7
  • 20