Horizontal border across entire row of CSS GRID
Asked Answered
I

4

16

I need to use a grid layout but also need a horizontal line separating each row.

The only thing I've been able to find is applying a border to each cell, but this only works if there are enough cells to fill each row.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.box {
  border-bottom: 2px solid #ffa94d;
  padding: 1em;
}
<div class="wrapper">
  <div class="box">One</div>
  <div class="box">Two</div>
  <div class="box">Three</div>
  <div class="box">Four</div>
</div>

Is there a way to fix the above so that the entire row has a border?

Issue answered 28/6, 2018 at 14:34 Comment(4)
possible workaround: https://mcmap.net/q/222623/-preventing-double-borders-in-css-gridDempster
@Michael_B Oh I also answered that one :p ... but it will only work if the grid is completely filledElmiraelmo
I understand. That's why I posted it as a "possible" solution, in case the OP wishes to adjust the layout for that method. @TemaniAfifDempster
.wrapper { display: grid; grid-template-columns: repeat(auto-fill, 1fr); grid-template-rows: repeat(auto-fill, 100px); } does not work?Waldowaldon
E
15

Add a grid-gap equal to the width of your border then consider gradient to achieve this:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  grid-row-gap:2px;
  background:
    repeating-linear-gradient(to bottom,
      #0000 0 100px, #ffa94d 0 102px /*+2px here*/
    );
}

.box {
  padding: 1em;
}
<div class="wrapper">
  <div class="box">One</div>
  <div class="box">Two</div>
  <div class="box">Three</div>
  <div class="box">Four</div>
</div>

Another idea is to consider a pseudo-element that you add to the 1st,4th,7th .. (3n + 1)th element:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  overflow:hidden;
}

.box {
  position:relative;
  padding: 1em;
}
.box:nth-child(3n + 1)::after {
  content:"";
  position:absolute;
  bottom:0px;
  left:0;
  width:100vw;
  height:2px;
  background:#ffa94d;
}
<div class="wrapper">
  <div class="box">One</div>
  <div class="box">Two</div>
  <div class="box">Three</div>
  <div class="box">Four</div>
</div>
Elmiraelmo answered 28/6, 2018 at 14:40 Comment(2)
This is neat, but a shame we need such workarounds. What if the row height is auto?Kremer
@Kremer the second example should work with height auto or we can find another workaround if you have a specific caseElmiraelmo
M
9

Imagine your table as a collection of cells (much like an excel spreadsheet). You can create a simple cell class that you append to each of your grid items to manipulate the cells without affecting the table data itself. Consider:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  
  grid-row-gap: 20px;
}


.cell {
  position: relative;
  border-bottom: 2px solid #ffa94d;
}
<div class="wrapper">
  <!-- Here is your first row -->
  <div class="cell">One</div>
  <div class="cell">Two</div>
  <div class="cell">Three</div>

  <!-- Here is your second row -->
  <div class="cell">Four</div>
  <!-- You can extend the line by the number of cells per row -->
  <div class="cell"></div>
  <div class="cell"></div>
  
  <!-- Organize your html into row groups to easily visualize them -->
  <!-- This will produce a blank row with no line -->
  <div></div>
  <div>-- blank row --</div>
  <div></div>
  
  <!-- You can also control where the line begins and ends -->
  <div class="box cell">First Column Only</div>
  <div></div> <!-- No cells here.. We just want to underline the first column -->
  <div></div>
  
  <!-- 2nd and 3rd columns only -->
  <div></div>
  <div class="cell">Second Column</div>
  <div class="cell">Third Column</div>
  
  
  
</div>

Note that I only used a grid-row-gap. If you introduce a grid-gap, or a grid-column-gap, your lines will be broken at the column gaps (this may be the desired effect in some cases).

It is true that this is a more involved method of controlling the horizontal lines separating the grid and less "programmatic" and more micro-management-esque but, it does provide great control over introducing the lines into your grid.

The other answers were great options too! I just wanted to provide my two cents.

Maura answered 12/5, 2020 at 14:50 Comment(1)
justify-items: center causing hr line not entirely spanning..What should I do?Tetraploid
H
2

This can be achieved with a pseudo element, absolutely positioned. It will override the grid-gap. You will have to set it to a wide width, which is only a little hacky, then set the overflow on the container to hidden.

body {
  margin:0;padding:0;
}

.products {
  display:grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  grid-gap:20px;
  overflow:hidden;
  border-bottom:1px solid black;
}

.card-product {
  position:relative;
  text-align:center;
}
.card-product:after {
  content:'';
  position:absolute;
  border-bottom:1px solid black;
  top:-20px;left:0;
  height:1px;
  width:1000%;
}
<section class="products">

  <article class="card-product">  
    <h3 class="card-product__title">
      Product Title
    </h3>
    <h4 class="card-product__sub">
      Product Category
    </h4>
  </article>

  <article class="card-product">  
    <h3 class="card-product__title">
      Product Title
    </h3>
    <h4 class="card-product__sub">
      Product Category
    </h4>
  </article>

  <article class="card-product">  
    <h3 class="card-product__title">
      Product Title
    </h3>
    <h4 class="card-product__sub">
      Product Category
    </h4>
  </article>
  
  <article class="card-product">  
    <h3 class="card-product__title">
      Product Title
    </h3>
    <h4 class="card-product__sub">
      Product Category
    </h4>
  </article>

  <article class="card-product">  
    <h3 class="card-product__title">
      Product Title
    </h3>
    <h4 class="card-product__sub">
      Product Category
    </h4>
  </article>

  <article class="card-product">  
    <h3 class="card-product__title">
      Product Title
    </h3>
    <h4 class="card-product__sub">
      Product Category
    </h4>
  </article>

  <article class="card-product">  
    <h3 class="card-product__title">
      Product Title
    </h3>
    <h4 class="card-product__sub">
      Product Category
    </h4>
  </article>

</section>
Hippo answered 10/5, 2021 at 6:0 Comment(2)
the problem with your solutions is it give uneven spacing bw rows and separating lineTrapezius
Unfortunately the "overflow hidden" to hide the overly long line will result in not being able to scroll hidden items in smaller windows.Sensitometer
D
0

The box class puts a border in the grid children, and you can make a grid children grow to fill any number of columns; below there's an example, where definig the class span3, the fourth grid child spans for 3 columns.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.box {
  border-bottom: 2px solid #ffa94d;
  padding: 1em;
}
.span3 {
  grid-column-end: span 3;
}
<div class="wrapper">
  <div class="box">One</div>
  <div class="box">Two</div>
  <div class="box">Three</div>
  <div class="box span3">Four</div>
</div>
Drees answered 13/10, 2022 at 17:54 Comment(2)
could you explain what needs to be added/updated in short before displaying all the codes?Praetor
@Praetor I already update my answer, the idea is use a class that spans the children of the grid.Anu

© 2022 - 2024 — McMap. All rights reserved.