Overview

It happened half a month ago, when a Table component was being developed. The body of the table is rendered using div as the cell, and the header part is rendered using the native table tag. When the result width is adapted, the header and body cannot always be aligned synchronously, and there is an error of a few pixels.
Finally, it was discovered that when the browser renders table-related elements, it does not support decimal rendering.

Analyze the reasons

Write a demo first

<div class="stage">
    <table class="table">
    <tr>
        <td>Content</td>
    </tr>
    </table>
</div>

<style>
* {
    padding: 0;
    margin: 0;
}
.stage {
    width: 100.5px;
    height: 100px;
    background-color: red;
}

.table {
    width: 100.5px;
    background-color: blue;
}
</style>

Chrome browser effects are as follows:
table小数渲染误差

In fact, as long as it is a floating point number, it will be truncated directly, so the effect of setting 100px is the same as setting 100.1px, 100.5px, and 100.9px.

This is really unbearable. I directly asked the Internet for help and found that there was very little relevant information, and the official website did not have relevant explanations. Many reasons were found, such as:

  1. The smallest rendering unit of the browser.

This is obviously not convincing. Although the browser confirms that there is a minimum rendering unit, it cannot explain that div can render floating point numbers, but table cannot.

  1. stackoverflow has talked about this

I didn't fully understand what the root cause was.
However, no matter what the reason, you must first come up with a set of solutions, the construction period can not be missed!

solution

I thought about a compatible solution, but at that time, I also thought of a way to deal with it.

The idea is very simple, that is, the cell width is rounded down and distributed equally, so that the actual cumulative width must be smaller than the ideal, and then the difference is distributed according to the index, so that although some cells are 1px wide, But it does not affect the visual effect.

After thinking about this solution, I found that this solution is the same as how to ensure that the sum of a set of data percentages is 100%.

/**
 * @param {*} baseWidth 期望宽度
 * @param {*} cols 列数
 * @returns 每列宽度的集合
 */
function adjustWidth(baseWidth, cols) {
  const cellWidth = Math.floor(baseWidth / cols); // 计算基准单元格width
  const offset = baseWidth - cellWidth * cols; // 偏差值
  const results = new Array(cols).fill(cellWidth);
  // 如果有冗余,再次分配
  for (let i = 0; i < offset; i++) {
    results[i] = cellWidth + 1;
  }
  return results;
}
adjustWidth(1000, 3); // [ 334, 333, 333 ]

donglegend
910 声望82 粉丝

长安的风何时才能吹到边梁?


引用和评论

0 条评论