user479870
user479870

Reputation:

show border grid lines only between elements

I'd like to use the CSS border attribute to make a fine 1px grid between span elements, like so.

     |    
  1  |  2  
-----|-----
  3  |  4  
     |    

This is what I currently have. It doesn't quite work obviously.

<html>
<head>
<style>
  div {
    width: 204px;
  }
  span {
    display: inline-block;
    height: 100px;
    width: 100px;
    border: 1px solid #ccc;
    border-left-width: 0;
    border-top-width: 0;
  }
</style>
</head>
<body>
<div><span>1</span><span>2</span><span>3</span><span>4</span></div>
</body>
</html>

When the div is set to 306px and the elements reflow, the solution should adapt dynamically.

     |     |
  1  |  2  |  3
-----|-----|-----
  4  |
     |

Preferably CSS only, or pure Javascript. Older browsers like IE7 can be ignored.

Upvotes: 14

Views: 60632

Answers (4)

Code Whisperer
Code Whisperer

Reputation: 23652

  1. Make the background color of the containing element the color you want for the border.
  2. Make the background color of the elements within the grid the color you really want as the background.
  3. Add a gap of 1, or the desired border thickness.
.grid {
  display: grid;
  background-color: orange;
  gap : 1;  
}

.grid > * {
  background-color: blue;
}

how it looks

Upvotes: 1

eriklharper
eriklharper

Reputation: 2978

I came up with this approach, which I think works pretty well with minimal CSS and hacks: https://codepen.io/eriklharper/pen/JMKMqa

    .border {
      background-color: gray;
    }
    .grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(auto, auto));
      grid-gap: 1px;
    }
    .grid > div {
      background-color: white;
      padding: 10px;
    }
    <div class="border">
      <div class="grid">
        <div>Item 1</div>
        <div>Item 2</div>
        <div>Item 3</div>
        <div>Item 4</div>
      </div>
    </div>

It introduces an extra wrapping element around the whole grid (which isn't perfect either) but I've found this to be a worthwhile compromise, despite. The lack of ability to simply style the grid-gaps directly is a shortcoming with CSS Grid that should be addressed with the spec.

Upvotes: 25

user479870
user479870

Reputation:

I'm using this solution, which automatically sets the border.

http://jsfiddle.net/aLz2T/3/

HTML

<div><span>1</span><span>2</span><span>3</span><span>4</span></div>​

CSS

div {
    width: 204px; /* adjust to get less/more columns */
}

span {
    display: inline-block;
    height: 100px;
    width: 100px;
    border: 1px solid #ccc;
    border-left-width: 0;
    border-top-width: 0;
}​

JavaScript

var a = document.querySelector('div');

// columns
var b = parseInt(a.offsetWidth / (100 + 2), 10);

for(var c, d = document.querySelectorAll('span'), e = d.length, i = 0; c = d[i]; i++) {
    // column
    c.style.borderRightWidth = ((i + 1) % b) != 0 ? "1px" : "0";
    // row
    c.style.borderBottomWidth = parseInt(i / b, 10) * b < e - b ? "1px" : "0";
}​

Upvotes: 1

VisioN
VisioN

Reputation: 145388

1. HTML+CSS solution

HTML:

<div>
    <i></i>
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
    <i></i>
</div>​

CSS:

div {
    position: relative;
    width: 202px;  /* or 303px (or 100px * n + n) */
    font-size: 0;
}

span {
    display: inline-block;
    height: 100px;
    width: 100px;
    border: 1px solid #ccc;
    border-left-width: 0;
    border-top-width: 0;
    font-size: 12px;
}

i {
    position: absolute;
    background: #fff;
    height: 1px;
    bottom: 0;
    left: 0;
    width: inherit;
}

​i:first-child {
    height: auto;
    width: 1px;
    top: 0;
    left: auto;
    right: 0;
}​

DEMO: http://jsfiddle.net/HTgKJ/


2. HTML+CSS+JavaScript solution

HTML+CSS:

<!-- See approach 1. -->

JavaScript:

var block = document.querySelectorAll(".block");
for (var i = 0; i < block.length; i++) {
    var spanWidth = block[i].querySelector("span").clientWidth,
        n = Math.floor(block[i].clientWidth / spanWidth);
    
    block[i].querySelector("i:first-child").style.left =
        (n * spanWidth + (n - 1)) + "px";
}​

DEMO: http://jsfiddle.net/HTgKJ/1/

Upvotes: 4

Related Questions