J.B. Langston
J.B. Langston

Reputation: 410

Consistent CSS border width with zoom

I have a 4K monitor with my Windows scaling set to 150% and my Chrome zoom set to 100%. On the website I am developing using Bootstrap 4.5.2, this causes Chrome to display table borders with inconsistent thickness. Notice in the following screeshot how there are two groups of 4 lines that are thicker than the rest (you may need to zoom the image):

enter image description here

Here is a small example to reproduce the problem on Chrome 95.0.4638.69. This is reproducible with the zoom set to 150% either in Chrome or in Windows display settings.

<!DOCTYPE html>
<html>
    <head>
        <title>Annoying Borders</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    </head>
    <body>
        <table class="table table-sm">
            <thead>
                <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            </thead>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
            <tr><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td><td>lorem ipsum</td></tr>
       </table>
    </body>
</html>

My understanding is that this is due a rounding error where the calculated border thickness is somewhere between 1 and 2 pixels, so sometimes Chrome shows 1px and sometimes 2px. Before asking, I searched and found a suggested workaround of using 0.01px for border thickness. This does work, but it doesn't really address the root cause, and apparently can cause border not to display at all on some browsers.

When I inspect the HTML for sites like Stack Overflow or GitHub, they are using 1px for the border widths on their divs, the same as me, but their borders are always consistent. For example, look at the borders between questions on Stack Overflow, or the borders between files in the GitHub repo browser). Zooming does affect the border width on these sites; if I zoom way in, the border grows to 2px, for example, but all of the borders grow consistently. I have poked around in their CSS for quite some time but I can't figure out how they did it. Am I missing some magic CSS setting that fixes this problem? Or do the borders on divs and table cells behave fundamentally differently?

Upvotes: 1

Views: 3484

Answers (2)

ddekany
ddekany

Reputation: 31122

If you only need horizontal lines (as on the picture), there's a painful workaround. Instead of using table borders, put div-s into every td, and set the top border of those div-s. Also if you need a border under the last tr, you have to add an extra empty tr with 0 content height, so that visually it will be just the border.

<html>
  <head>
    <style>
      /** ------------------------------------------------------------- */
      /** horizontal-borders-table                                      */
      /** ------------------------------------------------------------- */
      
      table.horizontal-borders-table {
        /* Get rid of unwanted spacing */
        border-collapse: collapse;
        border: 0;
      }
      .horizontal-borders-table td {
        /* Get rid of unwanted spacing */
        border: 0;
        padding: 0;
        vertical-align: top;
      }
      .horizontal-borders-table .td-content {
        border-top: var(--horizontal-border);
      }
      .horizontal-borders-table .closing-empty-tr .td-content {
        /* Ensure that we only have the border */
        padding: 0;
      }
      
      /** ------------------------------------------------------------- */
      /** Style for a specific table that uses horizontal-borders-table */
      /** ------------------------------------------------------------- */
      
      .example-table {
        --horizontal-border: 1px solid #000;
      }
      .example-table .td-content {
        /* Padding must be set on td-content, not on the td itself: */
        padding: 4px;
      }
    </style>
  </head>
  <body>
    <table class="horizontal-borders-table example-table">
      <tr>
        <td><div class="td-content">1</div></td>
        <td><div class="td-content">2</div></td>
        <td><div class="td-content">3</div></td>
      </tr>
      <tr>
        <td><div class="td-content">1</div></td>
        <td><div class="td-content">2<br>non-uniform</div></td>
        <td><div class="td-content">3</div></td>
      </tr>
      <tr>
        <td><div class="td-content">1</div></td>
        <td><div class="td-content">2</div></td>
        <td><div class="td-content">3</div></td>
      </tr>
      <tr class="closing-empty-tr">
        <td><div class="td-content"></div></td>
        <td><div class="td-content"></div></td>
        <td><div class="td-content"></div></td>
      </tr>
    </table>
  </body>
</html>

Some may wonder if this could be generalized to have all the borders (the whole gird), and almost, but there's a problem if the td content height is not uniform in the row, since you can't tell the div to fill the dynamic height of the td (as far as I know).

Upvotes: 0

Utmost Creator
Utmost Creator

Reputation: 1121

Most probably, this is a chrome-based browser bug, as the Firefox browser handles/renders it appropriately.

You could report the bug to the chrome team by using this bug report link

Consider making a media query for huge screens (e.g. more than 2k would have different border sizes).

@media screen and (min-width: 2560px) {
  table, table * {
    border: solid 1px black !important;
  }
  /* or */
  * {
    border: solid 1px black !important;
  }
}

You could change the min-width for your liking. Also, it is better to avoid using !important and specify one extra Specificity (class, tag name).

Upvotes: 1

Related Questions