16

My layout is something like this (I'm typing a simplified version with inline styles instead of classes)

.qa {
  border-bottom: 1px solid #ccc;
}
<div style="display: flex; flex-wrap: wrap; flex-direction: row">
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
</div>

This basically renders something like this:

enter image description here

My questions is:

How do I get rid of the border in the last row?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
supersan
  • 5,671
  • 3
  • 45
  • 64

7 Answers7

12

You can add a negative bottom margin to your elements then hide the overflow. This will hide the unwanted borders.

.qa {
  border-bottom: 1px solid #ccc;
  margin-bottom:-1px;
  margin-top:1px; /*to rectify the bottom margin, we can also consider padding-bottom*/
  
  /*irrelevant styles*/
  padding: 5px;
  margin-left:5px;
  margin-right:5px;
  box-sizing: border-box;
  flex:1 1 40%;
}

.wrapper {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  overflow:hidden;
}
<div class="wrapper">
  <div class="qa">
    <div>Question</div>
    <div>Answer<br>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer<br>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa">
    <div>Question</div>
    <div>Answer<br>Answer</div>
  </div>
</div>

This trick should work even if the number of element in a row is different from 2:

.qa {
  border-bottom: 1px solid #ccc;
  margin-bottom:-1px;
  margin-top:1px;
  
  
  /*irrelevant styles*/
  padding: 5px;
  margin-left:5px;
  margin-right:5px;
  box-sizing: border-box;
  flex:1 1 20%;
}

.wrapper {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  overflow:hidden;
}
<div class="wrapper">
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer<br> answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer<br> answer</div>
  </div>
</div>

It will also work with a reponsive layout where the number of columns can change on small screens:

.qa {
  border-bottom: 1px solid #ccc;
  margin-bottom:-1px;
  margin-top:1px;
  
  
  /*irrelevant styles*/
  padding: 5px;
  margin-left:5px;
  margin-right:5px;
  box-sizing: border-box;
  flex:1 1 20%;
}

.wrapper {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  overflow:hidden;
}

@media all and (max-width:800px) {
  .qa {
    flex:1 1 30%;
  }
}

@media all and (max-width:400px) {
  .qa {
    flex:1 1 40%;
  }
}
<div class="wrapper">
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer<br> answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" >
    <div>Question</div>
    <div>Answer<br> answer</div>
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 1
    This is great out of the box thinking! and it covers both flex row and columns. That's why I love SO, you get to learn so much! thanks – supersan Apr 02 '19 at 19:55
  • @supersan yes exactly ;) it will cover all the different configuration and more important the responsive part as I am sure that your layout will change to one column for example on small screens. – Temani Afif Apr 02 '19 at 20:19
  • .wrapper { overflow:hidden; } has often negative side-effects ... only as a remark ... – Sachbearbeiter Jan 12 '23 at 12:44
10

1: Use Another CSS class

We can create another CSS class which removes any styling form an existence element

.no-border {
  border-bottom: none;
}

Then add this class to the html element e.g.

  <div class="qa no-border" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>

2: Use CSS pseudo selector


.qa:last-child {
  border-bottom: none;
}

.qa:nth-last-child(2) {
    border-bottom: none;
}
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
KhaledMohamedP
  • 5,000
  • 3
  • 28
  • 26
  • they are called pseudo classes (https://developer.mozilla.org/fr/docs/Web/CSS/Pseudo-classes) – Temani Afif Apr 02 '19 at 19:40
  • never realized it would always be the last and second last element. the layout makes it look like it's the 3rd element and 6th element. thanks – supersan Apr 02 '19 at 19:48
4

Don't think about it as border-bottom.

Think about it as border-top and exclude the first two elements.

So instead of this:

.qa { border-bottom: 1px solid #ccc; }

Try this:

.qa + .qa + .qa { border-top: 1px solid #ccc; }

.qa + .qa + .qa {
  border-top: 1px solid #ccc;
}
<div style="display: flex; flex-wrap: wrap; flex-direction: row">
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
</div>

The next-sibling combinator (+) targets an element that is immediately preceded by another element, and both share the same parent.

So .qa + .qa would target only .qa elements that are preceded by one .qa element.

.qa + .qa + .qa targets only .qa elements that are preceded by two .qa elements.


Alternatively, you can try this:

.qa:nth-child(n + 3) { border-top: 1px solid #ccc; }

.qa:nth-child(n + 3) {
  border-top: 1px solid #ccc;
}
<div style="display: flex; flex-wrap: wrap; flex-direction: row">
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>


</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
4

judging by your layout, the items are numbered:

  [1]  [2]
  [3]  [4]
  [5]  [6]

now, you can either:

  • remove border-bottom from 5th & 6th items
.qa {
  border-bottom: 1px solid #ccc;
}

.qa:nth-of-type(5),
.qa:nth-of-type(6) {
  border-bottom: none;
}
  • add border-bottom to 1st-4th items:
.qa:nth-of-type(n+5) {
  border-bottom: 1px solid #ccc;
}
  • do similar math but for adding border-top

you can also flip the flex direction to make it more "reasonable" but also requires a fixed height (needed for wrapping, see here):

.container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

which numbers items in a different orientation:

  [1]  [4]
  [2]  [5]
  [3]  [6]

now you reomove border-bottom on every 3rd item:

.qa {
  border-bottom: 1px solid #ccc;
}

.qa:nth-of-type(3n) {
  border-bottom: none;
}

there are more complex fixes as well. for instance, you can group items in rows and apply border on row based selectors. This will be closest to what you really intended in the first place:

.row .qa {
  border-bottom: 1px solid #ccc;
}

.row:last-of-type .qa {
  border-bottom: none;
}
zhirzh
  • 3,273
  • 3
  • 25
  • 30
1

If you can add a :after pseudo Element in parent container of .qa (make sure your parent container is set to position: relative; or position: absolute;)

Css for .qa parent element

{
    content: "";
    position: relative;
    bottom: 0;
    left:0;
    right:0;
    height: /* set this to your (bottom padding of container + bottom margin of .qa box + border width)  */
    background: #fff; /* match this with your parent element background colour*/
}
vaku
  • 697
  • 8
  • 17
1

You could use border-top and remove the first two with the :nth-child CSS selector. Like this:

.qa {
  border-top: 1px solid #ccc;
}

.qa:nth-child(-n+2) {
  border-top: none;
}
<div style="display: flex; flex-wrap: wrap; flex-direction: row">
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
</div>
aridlehoover
  • 3,139
  • 1
  • 26
  • 24
0

I don't like adding a rule when you know you're immediately going to overwrite it, so here's a slightly different version of aridlehoover's answer with only one CSS rule.

.qa:not(:nth-child(-n+2)) {
  border-top: 1px solid #ccc;
}
<div style="display: flex; flex-wrap: wrap; flex-direction: row">
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
  <div class="qa" style="width:50%;">
    <div>Question</div>
    <div>Answer</div>
  </div>
</div>
Geat
  • 1,169
  • 6
  • 17