show border grid lines only between elements

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.


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/


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";
}​