Ereold
Ereold

Reputation: 111

Centering a wrapped flex container

I have a list that I would like to display on user's screen and allow him to reorder by drag'n'drop. This part is working.

I'm trying to display the list in several columns because there are sometimes too many options to display in only one column (the number of elements is varying).

I've used flexbox to do so, but I can't get my list to be centered, the flex container dimensions don't fit to its content.

.params-order.overlay {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(30,30,30, 0.8);
    z-index: 999999;
    justify-content: center;
    align-items: center;
}

.overlay-title {
  margin: 5% 5% 2%;
  color: white;
  text-align: center;
  text-shadow: 2px 2px 2px black;
}

.params-list {
  display: inline-flex;
  margin: 5%;
  flex-flow: column wrap;
  justify-content: center;
  align-items: center;
}

.params-list-item {
  background-color: rgb(240, 240, 240);
  border-radius: 5px;
  padding: 5px 15px 5px 25px;
  margin: 10px;
  list-style-type: none;
  width: 200px;
  position: relative;
  font-size: 1.4em;
  cursor: move;
}

.params-list-item::before {
  content: '';
  position: absolute;
  left: 7px;
  top: 19%;
  height: 64%;
  width: 6px;
  border: 2px dotted #999;
  border-top-width: 0;
  border-bottom-width: 0;
  box-shadow: none;
}
<div class="overlay params-order">
  <h3 class="overlay-title">Overlay title</h3>
  <ul class="params-list">
    <li class="params-list-item">Draggable 1</li>
    <li class="params-list-item">Draggable 2</li>
    <li class="params-list-item">Draggable 3</li>
    <li class="params-list-item">Draggable 4</li>
    <li class="params-list-item">Draggable 5</li>
    <li class="params-list-item">Draggable 6</li>
    <li class="params-list-item">Draggable 7</li>
    <li class="params-list-item">Draggable 8</li>
    <li class="params-list-item">Draggable 9</li>
    <li class="params-list-item">Draggable 10</li>
    <li class="params-list-item">Draggable 11</li>
    <li class="params-list-item">Draggable 12</li>
    <li class="params-list-item">Draggable 13</li>
  </ul>
</div>

I've provided a codepen: http://codepen.io/anon/pen/GpEGqd

I've been able to make it by adding self-align: stretch; on the .params-list, but it makes it take all width, and I don't want this because I'm using the params-list to track the click and remove the overlay.

How can I fix the alignment?

Upvotes: 1

Views: 1824

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 372264

I'm trying to display the list in several columns because there are sometimes too many options to display in only one column (the number of elements is varying).

I've used flexbox to do so, but I can't get my list to be centered, the flex container dimensions don't fit to its content.

Your list is already centered horizontally as a single column. My understanding of your question is you want the list to remain centered when the column wraps.

The reason the list isn't wrapping is because you haven't defined a height for the container. Hence, the list will stack indefinitely in a single column because there's no height limit.

The second issue is the width. To center the nested flexbox within the container you need to define the frame of reference (i.e., specify the width of the container).

Try this:

.params-list {
    display: flex;
    margin: 5%;
    flex-flow: column wrap;
    justify-content: center;
    align-items: center;
    height: 300px; /* NEW */
    width: 100%; /* NEW */
}

The column now wraps because there's a height limit, and the centering occurs along the full width of the container.

DEMO: http://codepen.io/anon/pen/jbwpyV


UPDATE

Question comment:

The width: 100% do the job, but I don't want my list to take 100% when it doesn't need to, because I'm tracking the clicks outside of it to know when to remove the overlay. Isn't it possible to have the .params-list width to fit its content?

Well, you're asking the nested flexbox with a column alignment to be horizontally centered in the container. In order to be centered, you need to define the width of the container, which would be width: 100%. If you confine .params-list to only the width of its content, you're still not defining the frame of reference for centering in the container. .params-list with multiple columns still needs to know: Where should I center myself?

You can test this in the demo by adding and removing the width: 100% in .params-list.

DEMO: http://codepen.io/anon/pen/jbwpyV

However, if you change the flex-direction to row, then the flex items will stack and wrap in a row, and take up only the amount of width they need. In other words, you won't need to define width.

DEMO: http://codepen.io/anon/pen/QjgBVv

Otherwise, you may want to consider alternative solutions:

Upvotes: 2

Related Questions