Search code examples
htmlcssflexboxborder

Prevent double borders around side-by-side elements


If you have multiple containers with 1px border, all containers next to each other generate a 2px border. So in order to get rid of that you always set e.g. border-right: none; and then add border-right: 1px; to the last child to make all containers have 1px border in all sides.

But if you use flexbox flex-basis rule to break containers into next line, it breaks whole border-right idea, the last container in the line before the break always stays left out with no border.

e.g. in this example I have 5 containers, but I want 4 per line and when it breaks into new line, you can see the border-right issue:

.wrapper {
  display: flex;
  flex-wrap: wrap;
  width: 400px;
}

.container {
  flex-basis: 20%;
  border: 1px solid #000;
  border-right: none;
  margin-bottom: 1px;
  min-height: 100px;
  width: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.container:last-child {
  border-right: 1px solid #000;
}
<div class="wrapper">
  <div class="container">1</div>
  <div class="container">2</div>
  <div class="container">3</div>
  <div class="container">4</div>
  <div class="container">5</div>
</div>

https://jsfiddle.net/45kngj9p/


Solution

  • Since you know how many flex items there are in each row, you can use the :nth-child() selector to apply borders to items missed by the main rule.

    .wrapper {
      display: flex;
      flex-wrap: wrap;
      width: 400px;
    }
    .container {
      flex-basis: 20%;
      border-top: 1px solid #000;
      border-bottom: 1px solid #000;
      border-right: 1px solid #000;
      margin-bottom: 1px;
      min-height: 100px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .container:nth-child(4n + 1) { /* add border to first child in each row */
      border-left: 1px solid red;
    }
    <div class="wrapper">
      <div class="container">1</div>
      <div class="container">2</div>
      <div class="container">3</div>
      <div class="container">4</div>
      <div class="container">5</div>
    </div>
    
    <hr>
    
    <div class="wrapper">
      <div class="container">1</div>
      <div class="container">2</div>
      <div class="container">3</div>
    </div>
    
    <hr>
    
    <div class="wrapper">
      <div class="container">1</div>
      <div class="container">2</div>
      <div class="container">3</div>
      <div class="container">4</div>
      <div class="container">5</div>
      <div class="container">6</div>
      <div class="container">7</div>
      <div class="container">8</div>
      <div class="container">9</div>
      <div class="container">10</div>
    </div>