1

Problem

I am currently trying to left-align blocks within a centered wrapper with dynamic width. I can't get this to work using only HTML/CSS.

Here is a JSFiddle: https://jsfiddle.net/hudxtL8L/


Examples

So currently, it looks like this:

|  _____   _____           |
| |     | |     |          |
| |     | |     |          |
| |_____| |_____|          |
|  _____   _____           |
| |     | |     |          |
| |     | |     |          |
| |_____| |_____|          |
|  _____                   |
| |     |                  |
| |     |                  |
| |_____|                  |
|                          |

And I want it to look like this:

|       _____   _____      |
|      |     | |     |     |
|      |     | |     |     |
|      |_____| |_____|     |
|       _____   _____      |
|      |     | |     |     |
|      |     | |     |     |
|      |_____| |_____|     |
|       _____              |
|      |     |             |
|      |     |             |
|      |_____|             |
|                          |

or, on a bigger device, something like this:

|       _____   _____   _____     |
|      |     | |     | |     |    |
|      |     | |     | |     |    |
|      |_____| |_____| |_____|    |
|       _____   _____   _____     |
|      |     | |     | |     |    |
|      |     | |     | |     |    |
|      |_____| |_____| |_____|    |
|       _____                     |
|      |     |                    |
|      |     |                    |
|      |_____|                    |
|                                 |

The important thing here is that the last row is not centered, but left-aligned within the centered parent. Can this be done, and if so, how? I tried different approaches but all of them failed.


Tried approaches

margin: 0 auto will not work since it requires a fixed width, but I want as many .element's as possible per row.

Using a table seems difficult as well, since I don't know how many .element's will fit in one row on the current device.

Using javascript will of course work, but I have the feeling that there is a CSS-only solution to this.

BlackWolf
  • 5,239
  • 5
  • 33
  • 60
  • After rereading your question, I was wondering if you want to elements in a row regardless of the the viewport width? – Marc Audet May 21 '16 at 13:20
  • 1
    the number of elements in a row should be dynamic, depending on viewport width. I probably should have made that clearer, I'm going to edit the question – BlackWolf May 21 '16 at 14:07
  • Ok, this is a bit clearer, will take a second look. – Marc Audet May 21 '16 at 15:26

3 Answers3

1

Use can use CVS flex to realize this layout.

One approach is to define a container, #content that has a fixed width and center it with margin: 0 auto.

Apply the flex properties to #content, use justify-content: space-between to get the child elements in the desired positions.

The child .elements need flex-basis: 100px to specify the width within the flex container context.

You can control the spacing between elements using margins.

Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout

#viewport {
  border: 1px solid black;
}
#content {
  width: 250px;
  margin: 0 auto;
  border: 1px dashed blue;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
.element {
  border: 1px dotted black;
  flex-basis: 100px;
  height: 100px;
  margin: 10px; /* optinal, gives you some control on spacing */
}
<div id="viewport">
  <div id="content">
    <div class="element">1</div>
    <div class="element">2</div>
    <div class="element">3</div>
    <div class="element">4</div>
    <div class="element">5</div>
  </div>
</div>
Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • This partly works and seems to be the best solution so far. The issue with this seems to be that the spacing between elements is not constant, but dependent on the width of `#content`. – BlackWolf May 21 '16 at 14:16
  • You are exactly right. It was not clear to me how many elements per row you wanted (I assumed 2) and also, what determines the spacing between elements. In my example, the spacing between the elements is the width of the `#content` container minus 2 times the width of the inner child element. I just reread your comments above and will rethink the solution. – Marc Audet May 21 '16 at 15:25
0

Is this what you want:

#content {
  width: 300px;
  border: 1px solid red;
}
#outer {
  text-align: center;
  border: 1px solid green;
}

#inner {
  display: inline-block;
  text-align: left;
  border: 1px solid blue;
  padding: 20px;
}

.element {
  display: inline-block;
  border: 1px solid black;
  width: 100px;
  height: 100px;
  margin-left: 15px;
}
Dominic Wearne
  • 13
  • 1
  • 1
  • 5
  • no, unfortunately this does not work. this just manually places the boxes, but does not work with a dynamic `#content` width – BlackWolf May 21 '16 at 10:19
0
 #inner {
    display: block;
    text-align: left;
    border: 1px solid blue;
    text-align:center;
    -moz-text-align-last: left;
      text-align-last: left;
  }
  .element:last-child {
     margin-left:20px;
  }

Use text-align-last: left

Krishna Rana
  • 379
  • 1
  • 2
  • 11
  • as with the other answers, this unfortunately breaks with other `#content` widths. I updated the question so hopefully it is clearer now that `#content`'s width is supposed to be dynamic. – BlackWolf May 21 '16 at 10:22
  • You can refer to this question http://stackoverflow.com/questions/19527104/left-aligned-last-row-in-centered-grid-of-elements – Krishna Rana May 21 '16 at 10:35