7

I'm displaying list items in columns by using flexbox. Items should wrap into more columns after a specific height, columns should be centered horizontally, and list items within each column should be left justified. I'm using max-height to limit list height, flex-flow: column wrap to build wrapping columns, and align-content: center to center the columns.

I realize a multi-column solution might be more obvious, but I don't want to define column-width or column-count, so I opted for a flexbox solution.

The Problem
Columns are only centered horizontally when items wrap to multiple columns. If there is only one column, then the column is not centered. I see this behavior in Chrome 63 on both Windows 10 Home and MacOS Sierra. In Firefox, it looks the way I intended (screenshots below).

Am I missing something?
How can I get the column(s) to always be horizontally centered, cross-browser?

.filter_drop {
  display: flex;
  flex-flow: column wrap;
  align-content: center;
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 7em;
  border-bottom: 1px solid black;
}

.filter_drop li {
  margin: 0 1em 0 0;
  line-height: 1.2;
}
<ul class="filter_drop">
  <li>One</li>
  <li>Two </li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
  <li>Six</li>
  <li>Seven</li>
  <li>Eight </li>
  <li>Nine</li>
  <li>Ten</li>
  <li>Eleven</li>
  <li>Twelve</li>
</ul>
<ul class="filter_drop">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
  <li>Six</li>
  <li>Seven</li>
</ul>
<ul class="filter_drop">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
</ul>
<ul class="filter_drop">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

View on JSFiddle


Chrome 63:
Chrome Layout

Firefox 57:
Firefox Layout

showdev
  • 28,454
  • 37
  • 55
  • 73
  • 1
    If you are interested, there is a fix for the _left align_ w/o assign a fixed width: https://jsfiddle.net/gznyyegn/ ... if you like I can post this as an answer. The `translate` is needed to overcome yet another Flexbox bug: https://stackoverflow.com/questions/33891709/when-flexbox-items-wrap-in-column-mode-container-does-not-grow-its-width – Asons Dec 19 '17 at 20:12
  • Thanks @LGSon. Interesting idea, but I [couldn't quite get the centering to work](https://jsfiddle.net/gznyyegn/3/). Maybe because of the issue you linked? – showdev Dec 19 '17 at 20:56
  • Yes, it is...didn't check with wider text in one of the elements, but see know it won't work fully dynamic. It works prefect in Edge though (version 16, Falls Creators Update), which have fixed the bug :) – Asons Dec 19 '17 at 21:14

1 Answers1

2

align-content works only when there are multiple lines in the flex container.

align-items or align-self is needed to align a single line.

Here's a complete explanation:

.filter_drop {
  display: flex;
  flex-flow: column wrap;
  align-content: center;
  align-items: center; /* NEW */
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 7em;
  border-bottom: 1px solid black;
}

.filter_drop li {
  margin: 0 1em 0 0;
  line-height: 1.2;
}
<ul class="filter_drop">
  <li>One</li>
  <li>Two </li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
  <li>Six</li>
  <li>Seven</li>
  <li>Eight </li>
  <li>Nine</li>
  <li>Ten</li>
  <li>Eleven</li>
  <li>Twelve</li>
</ul>
<ul class="filter_drop">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
  <li>Six</li>
  <li>Seven</li>
</ul>
<ul class="filter_drop">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
</ul>
<ul class="filter_drop">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • That seems to help. But I want the list items to be text-aligned to the left, so each column is left justified. Sorry, I should have mentioned that. – showdev Dec 19 '17 at 17:51
  • The FF image is what I want. The columns are centered, but the items within each column are left-justified. I'm reading the post you linked about mult- vs single-line flexboxes. Maybe what I'm trying to do is not the way flexbox works. But then it's weird that it works in FF... – showdev Dec 19 '17 at 18:00
  • 2
    I understand. The reason the boxes are centered in their column is because they center *and* shrink-wrap their content. To left-align all the text, you need to give each box the same width. Then all boxes will center *and* be the same length, allowing text to align left down a column. https://jsfiddle.net/78mb4zna/4/ – Michael Benjamin Dec 19 '17 at 18:04
  • Hm, I see what you mean. It's not ideal, because I don't want to explicitly set the column width. But it might be necessary to achieve that layout with flexbox. Any idea why FF seems to `align-content` even with a single column? Thanks Michael. – showdev Dec 19 '17 at 18:10
  • 2
    Here's my theory: `align-content` applies only to multi-lline flex containers. A multi-line flex container is a container with `wrap` enabled. Firefox sees that your container is multi-line and allows `align-content` to work, whether or not there are multiple lines. The fact that the container is multi-line is enough for FF. Chrome, on the other hand, wants to see `wrap` enabled *and* for there to actually be multiple lines before it allows `align-content` to work. – Michael Benjamin Dec 19 '17 at 18:18
  • 2
    It seems to be a matter of interpretation of spec guidance. Neither appears to be wrong, but FF adheres more to the letter of the spec: *Is wrap enabled? Yes. Okay, then it's multi-line and `align-content` is set loose.* Chrome adds another step to the process. – Michael Benjamin Dec 19 '17 at 18:21
  • 2
    And keep in mind, that browser makers can at any time engage in an [**intervention**](https://github.com/WICG/interventions). I've seen Chrome do this before ([example](https://stackoverflow.com/q/36247140/3597276)). – Michael Benjamin Dec 19 '17 at 18:23