Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement separators between wrapped flex items?

Tags:

css

flexbox

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.

like image 960
papillon Avatar asked May 09 '26 01:05

papillon


2 Answers

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>
like image 65
Richard Hunter Avatar answered May 10 '26 14:05

Richard Hunter


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>
like image 25
G-Cyrillus Avatar answered May 10 '26 13:05

G-Cyrillus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!