乐趣区

关于table:table的宽高属性不支持小数渲染-奇葩

概述

事件产生在半个月前,过后正在开发一个 Table 组件。Table 的 body 应用 div 作为单元格渲染进去的,header 局部应用原生 table 标签渲染的,后果宽度适应的时候,header 和 body 总是无奈同步对齐,有几个像素的误差。
最初发现了是浏览器渲染 table 相干元素的时候,不反对小数渲染。

剖析起因

先写个 demo

<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 浏览器成果如下:

其实只有是浮点数,间接都会被截断,所以设置 100px 的成果和设置 100.1px、100.5px、100.9px 都是一样的。

这就真的不能忍了,间接求助网络,发现相干材料非常少,官网也没有相干阐明,查到不少起因,比方:

  1. 浏览器最小渲染单位。
    这个显著很没有说服力,尽管浏览器确认存在最小渲染单位,然而无法解释 div 能渲染出浮点数,而 table 不行。
  2. stackoverflow 有议论这个

根本原因到底是什么,我也没彻底搞懂。
不过,无论什么起因,必须先得拿出一套解决方案,工期不能误呀!

解决方案

本人推敲了一个兼容计划,过后也是眉头一皱; 计上心来,想到了一个解决形式。

想法非常简单,就是单元格宽度先向下取整,平均分配,这样理论累计的宽度 必定比 现实的小一点,而后把差进去的再依照索引进行调配,这样尽管有的单元格宽了 1px,然而不影响视觉效果。

想到这个计划之后,发现这个解决形式和之前解决的如何保障 一组数据百分比之和为 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]
退出移动版