1
votes

How do I implement separators between wrapped flex items?

This is the code sample to which I want to add separators:

.a {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.b {
  background-color: #F6E0E0;
  width: 105px;
  height: 80px;
}
<div class="a">
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
  <div class="b">b</div>
</div>

Each block should be separated from the ones on its left and right by a separator (a div of 1px width and 50px height and a background color for example). However, one block that is on the right edge of the container should not be separated by the next block, which is on the left edge of the container and on the next line. Since the wrapping is dynamic (for the style to be fluid), I can't add separators at specific positions.

I tried using borders or divs but I can't get a correct result. I also tried a workaround by setting justify-content to space-between and adding a margin-right of -1px to the separators, so that the ones on the right get out of the container, but I need justify-content to be set to space-around so this solution is not valid.

2
You'll need media queries for this - Paulie_D
Your solution so far doesn't appear to correspond to your description: I see no separators here. Could you show us the full implementation that you have so far so the problem is clearer? - Richard Hunter
@RichardHunter it is not a solution, it is the sample of code to which I want to add separators, my bad it was not clear. I'll update my post to explain this. - papillon
And i guess it should stand in the middle of the space in between 2 blocks no matter the width of the parent? What is your intend to use for the separators, a pseudo or an extra tag ? - G-Cyrillus
@G-Cyrillus exact, in the middle of the space in between 2 blocks. I intend to use separators as a graphic ornament. They will look like thin, light-grey, vertical bars between each element. - papillon

2 Answers

3
votes

I hope this is something like what you what. I've used calc() and css custom variables so you can plug in your own numbers to get the effect you want. Essentially, I've created the separator with a pseudo element and put it on the left side of the boxes. Then I've used negative margins on the container to shift the divider on the left most boxes outside of the container. Finally, a wrapping div with overflow:hidden hides the dividers.

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

.container {
  --divider: 2px;
  --column-gap: 20px;
  --border: 2px;
  background: pink;
  overflow: hidden;
}

.a {
  display: flex;
  flex-wrap: wrap;

  justify-content: flex-start;
  background: lightblue;
  margin-left: calc(var(--column-gap) / -2);
}

.b {
  background-color: #F6E0E0;
  width: 105px;
  border: solid var(--border) black;
  height: 80px;
  text-align: center;
  line-height: 80px;
  color: grey;
  position: relative;
  margin-bottom: 4px;
  margin-left: calc(var(--column-gap) / 2);
  margin-right: calc(var(--column-gap) / 2);
}

.b:after {
  content: '';
  position: absolute;
  right: 100%;
  top: 50%;
  display: inline-block;
  width: var(--divider);
  height: 50px;
  background-color: coral;
  transform: translateY(-50%);
  margin-right: calc(((var(--column-gap) - var(--divider)) / 2) + var(--border));
}
   <div class="container">
      <div class="a">
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
         <div class="b">b</div>
       </div>
    </div>
2
votes

You may use

  • a tag in between your div to style like a separator and
    add a negative margin, so the one on the end of a row will stand outside the container.(hr took for the demo below, it can be any you think the right one to use)
  • add the overflow:hidden to the parent to make it work;
  • if it comes from a template, hide the last one.
  • reset a margin to the div if you want to see the separotor anytime
  • reset also the right margin to the last .b box if an hr(or any tag of your choice) stands last .

demo of the idea below :

.a {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  /* hidding last hr on a row and recenter content*/
  overflow: hidden;  
  border-right:solid 1.5em transparent;
}

.b {
  background-color: #F6E0E0;
  width: 105px;
  height: 80px;
  position: relative;/* put it on top of seperator*/
  margin: 0.5em 1.5em;
}

hr {
  height: 50px;
  margin: auto -20px;
  /* border-reset*/
  border: none;
  border-left: 1px solid lightgray;
}

hr:last-child {/* there is one */
  display: none;
}

.b:nth-last-child(2) {/* harmless if there is no hr in last position   */
  margin-right: 0px;
}
<div class="a">
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
  <div class="b">b</div>
  <hr>
</div>