4

I have some items that I'd like to arrange in flex-box, so that they will wrap on smaller screens. flex-wrap:wrap; can do this.

When they are "unwrapped" (i.e. a wide screen), I'd like there to be a vertical line between the content elements. When the screen/container narrows, I'd like them to wrap to the next line and not have a border.

I want the entire thing to be in the centre of the page. It is not required that all the content elements have the same width.

Something like this:

enter image description here

I have seen Smart borders between flex items – the dumb way, but this doesn't work when the flex-box container is "floating" in the page, as it relies on a hidden -1px margin to hide the spare border, which means the items must stretch all the way to the left margin in order to hide their margins. For centred boxes, this is not always true.

/* Based on https://codepen.io/thatemil/pen/MrrJyZ 
 * used by
 * https://thatemil.com/blog/2018/01/08/direction-independent-borders-this-is-stupid/
 */
.container {
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
  justify-content: center;
}

.item {
  border-left: 1px solid red;
  margin-left: -1px;
  padding: 5px;
}
Short (unwrapped):

<div class="container">
  <div class="item" style="background-color:pink;">foobar</div>
  <div class="item" style="background-color:grey;">quux</div>
</div>

Long (wrapping):

<div class="container">
  <div class="item" style="background-color:pink;">foobar foobar foobar foobar foobar foobar</div>
  <div class="item" style="background-color:grey;">quux quux quux quux quux quux quux</div>
</div>
Inductiveload
  • 6,094
  • 4
  • 29
  • 55

1 Answers1

2

To achieve this behavior with **flexbox*, you would need a media query or some other trigger to remove the border on wrap. So unless you know when the items will wrap, such a solution isn't helpful. But here's a demo of a flex container using a pseudo-element as the divider.

jsFiddle demo

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.item {
  padding: 5px;
}

.item:first-child {
  order: 1;
}

.item:last-child {
  order: 3;
}

.container::before {
  order: 2;
  content: "";
  border-right: 2px solid red;
}
<div class="container">
  <div class="item" style="background-color:pink;">foobar foobar foobar foobar foobar foobar</div>
  <div class="item" style="background-color:grey;">quux quux quux quux quux quux quux</div>
</div>

Another possible option is CSS Grid. Use the background color of the container and the grid-column-gap property for the divider, and the auto-fit function for wrapping.

jsFiddle demo

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  background-color: red;
  grid-column-gap: 2px;
}

.item {
  padding: 5px;
}
<div class="container">
  <div class="item" style="background-color:pink;">foobar foobar foobar foobar foobar foobar</div>
  <div class="item" style="background-color:grey;">quux quux quux quux quux quux quux</div>
</div>

More info: https://stackoverflow.com/a/47887186/3597276

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701