Solving the Misalignment Between Antd Table Headers and Content Cells

· 3 min read

Recently, I encountered this styling issue, as shown in the image.

The image shows the problem.

How to Reproduce

Fixed table header with percentage width columns.

Investigation Steps

  • Testing showed that on Mac with Chrome Version 79.0.3945.130, this issue doesn’t occur
  • On Windows 10 with Chrome Version 79.0.3945.130, the issue exists
  • On Windows 10 with Edge, there’s no issue
  • Dragging the browser to an extended screen eliminates the issue

After comparing these scenarios, I found clues related to system, browser, different screens, and based on this direction of investigation, I finally determined the cause.

Problem Explanation

  1. PC screen display scaling settings affect page layout

    If you change it to 100%, the page redraws and the problem disappears

  2. On Windows, Chrome’s scroll pane takes up space by default, but on Mac it doesn’t. This is related to the operating system, not the browser version. Why doesn’t Mac have this issue? For example, in Chrome on Mac, the scroll pane is not calculated into the width, as if it’s on a different layer

  3. The direct cause of misalignment is that on Windows, when the device pixel ratio is not 1, the vertical scroll pane width of the table header is inconsistent with the scroll pane width of the table content, so the container width and table content width are inconsistent. Since we set the column widths as percentages, this causes the two widths to be different, resulting in this problem. When we manually change the computer’s scaling to 100%, the scroll pane widths become consistent, so there’s no misalignment issue. But why, when the device pixel ratio is not 1, are the table header’s vertical scroll pane and the table content’s scroll pane widths inconsistent? I don’t know, maybe both are bugs.

Device Pixel Ratio

Now that we understand the problem, let’s explore the underlying cause: device pixel ratio.

When we modify the scaling, we’re actually changing the device pixel ratio. If we set it to 150%, the device pixel ratio becomes 1.5, meaning that text that appears as 12px in CSS will physically display as 18px, although the CSS still shows 12px. This explains why sometimes web pages look like they have larger fonts than others.

We can also get the actual device pixel ratio by executing a JavaScript script.

How to Solve

With the problem identified, the solution is either to control the scrollbar widths to be consistent or to make the scrollbar width not count in calculations. Here, I directly set the scrollbar to not occupy space:


.ant-table-small>.ant-table-content .ant-table-header{
    overflow-y: overlay !important;
}

.ant-table-fixed-header>.ant-table-content>.ant-table-scroll>.ant-table-body{
    overflow-y: overlay !important;
}

Note that overlay is only supported in WebKit and Blink kernel browsers

Behaves the same as auto, but with the scrollbars drawn on top of content instead of taking up space. Only supported in WebKit-based (e.g., Safari) and Blink-based (e.g., Chrome or Opera) browsers.

From MDN

Also, the reason for adding !important here is that the scroll styles added by the antd component are inline styles, so this is necessary to make our solution work.

References

Authors
Developer, digital product enthusiast, tinkerer, sharer, open source lover