csshdpi

Why is a slight gap added between rows on HDPI screens, causing this striped effect?


I have a perplexing CSS issue, where multiple rows with background colour that should meet have a very slight gap in high DPI screens.

@font-face {
    font-family: 'Iosevka';
    font-style: normal;
    font-weight: 400;
    src: url(https://curiousdannii.github.io/parchment-testing/fonts/build/iosevka-custom-extended.woff2) format('woff2');
}

.BufferWindow {
    font-family: Georgia;
    font-size: 15px;
    line-height: 1.4;
    overflow-y: auto;
    scrollbar-gutter: stable;
}

.BufferLine {
    white-space: pre-wrap;
}

span.Style_preformatted {
    font-size: 1em;
    font-weight: normal;
    font-style: normal;
    font-family: Iosevka;
}

.reverse {
    background: black;
    color: white;
    display: inline-block;
}
<div class="BufferWindow">
    <div class="BufferLine Style_preformatted"><span class="Style_preformatted">         </span><span class="Style_preformatted reverse">   </span><span class="Style_preformatted"> </span><span class="Style_preformatted reverse">   </span></div>
    <div class="BufferLine Style_preformatted"><span class="Style_preformatted">         </span><span class="Style_preformatted reverse">       </span></div>
    <div class="BufferLine Style_preformatted"><span class="Style_preformatted">         </span><span class="Style_preformatted reverse">      </span><span class="Style_preformatted">  </span></div>
    <div class="BufferLine Style_preformatted"><span class="Style_preformatted">         </span><span class="Style_preformatted reverse">       </span></div>
    <div class="BufferLine Style_preformatted"><span class="Style_preformatted">         </span><span class="Style_preformatted reverse">       </span></div>
</div>

Screenshot showing how it's designed to look, on a non-HDPI screen:

Screenshot showing how it's designed to look, on a non-HDPI screen

Screenshot directly from my phone:

Screen shot from my phone

Screenshot from remote dev tools showing the height of one row, which is 21 pixels:

Screenshot from remote dev tools showing the height of one row

Screenshot from remote dev tools showing the height of all five rows, which is 107 pixels:

Screenshot from remote dev tools showing the height of all five rows

So on a non-HDPI screen the height of all five rows is 105 pixels, which is 5 times 21 pixels. Somehow on the HDPI screen it's adding two extra pixels.

So then I saw in dev tools that the height of the BufferLine isn't actually 21 pixels, it's 21.364:

screenshot from dev tools showing the BufferLine

I was wondering if it was that the line-height: 1.4 multiplier was producing something almost but not exactly 21 pixels high, which only becomes relevant on HDPI screens, but 15 * 1.4 = 21 exactly (I must have designed this sensibly in the past ;)). So I'm not sure what's cause that little bit extra in height.

How do I determine which part of my CSS is causing this, and how can I make it more reliable?


Solution

  • The arrangement you have is essentially this:

    Two rectangles, each depicting a character block, the same height but vertically offset from one another, making the height from the top of one two the bottom of the other greater than the height of the rectangles.

    (1/2L = Half Leading)

    The characters align by their baselines, but because the ascents and/or descents differ, their tops and bottoms don't align with one another, and the total height is greater than either of the characters.

    From this you should be able to see that the problem can be avoided by either using the same font throughout, or by reducing the line height of one of them, so that their half-leadings are so small (or negative) that the total top edge and bottom edge are both determined by the same character.