Search code examples
cssborderline-numberscss-counter

Continuous border across multiple elements


I am trying to add line numbers to a code snippet. It's working, except for the cosmetic detail that the border between the line number and the line of code isn't continuous. It has small, ugly gaps instead.

Inspect element doesn't seem to explain the spacing.

I have also tried fiddling with line-height, but nothing really worked without significantly affecting the spacing.

pre {
    counter-reset: linenum;
    font-family: "DejaVu Sans Mono";
}

pre code {
    counter-increment: linenum;
}

pre code::before {
    content: counter(linenum);
    display: inline-block;
    width: 3em;
    text-align: right;
    padding-right: 0.5em;
    margin-right: 0.5em;
    color: #888;
    border-right: 1px solid #888;
}
<pre>
<code>Line one</code>
<code>Line two</code>
<code>Line three</code>
</pre>


Solution

  • The issue is caused by the font-family set in pre, so simple fix is removing the font, which will default to monospace

    pre {
      counter-reset: linenum;
    }
    
    pre code {
      counter-increment: linenum;
    }
    
    pre code::before {
      content: counter(linenum);
      display: inline-block;
      width: 3em;
      text-align: right;
      padding-right: 0.5em;
      margin-right: 0.5em;
      color: #888;
      border-right: 1px solid #888;
    }
    <pre>
    <code>Line one</code>
    <code>Line two</code>
    <code>Line three</code>
    </pre>

    If you want to keep the font then you have a few approaches to achieve what you want:

    • Set display: grid in the pre

    pre {
      counter-reset: linenum;
      font-family: "DejaVu Sans Mono";
      display: grid;
    }
    
    pre code {
      counter-increment: linenum;
    }
    
    pre code::before {
      content: counter(linenum);
      display: inline-block;
      width: 3em;
      text-align: right;
      padding-right: 0.5em;
      margin-right: 0.5em;
      color: #888;
      border-right: 1px solid #888;
    }
    <pre>
    <code>Line one</code>
    <code>Line two</code>
    <code>Line three</code>
    </pre>

    • Set display: flex & flex-direction: columnm in the pre

    pre {
      counter-reset: linenum;
      font-family: "DejaVu Sans Mono";
      display: flex;
      flex-direction: column
    }
    
    pre code {
      counter-increment: linenum;
    }
    
    pre code::before {
      content: counter(linenum);
      display: inline-block;
      width: 3em;
      text-align: right;
      padding-right: 0.5em;
      margin-right: 0.5em;
      color: #888;
      border-right: 1px solid #888;
    }
    <pre>
    <code>Line one</code>
    <code>Line two</code>
    <code>Line three</code>
    </pre>

    • Set display: table-row in the code

    pre {
      counter-reset: linenum;
      font-family: "DejaVu Sans Mono";
      /*just be coeherent with table-row in the child */
      display: table
    }
    
    pre code {
      counter-increment: linenum;
      display: table-row
    }
    
    pre code::before {
      content: counter(linenum);
      display: inline-block;
      width: 3em;
      text-align: right;
      padding-right: 0.5em;
      margin-right: 0.5em;
      color: #888;
      border-right: 1px solid #888;
    }
    <pre>
    <code>Line one</code>
    <code>Line two</code>
    <code>Line three</code>
    </pre>