Skip to content

业务问题沉淀 - CSS 小数像素问题 #20

@wwyx778

Description

@wwyx778

CSS 小数像素问题

最近开发了一个可以限制最大行数的 Checkbox.Group 组件,期望用法是

<Checkbox.Group maxRows={2} options={[...]} />

则复选框选项最大只会展示2行,超出部分默认收起,点击展开按钮可展开,如图
image

功能和之前做的一个编辑器 Toolbar 很像,具体实现思路基本一致,区别就是展开按钮是单独的一行元素,不参与动态计算,所以实现起来更简单,不使用ResizeObserver也行。

实现

  useLayoutEffect(() => {
    if (checkboxGroupRef.current) {
      const rowHeight = checkboxGroupRef.current?.children?.[0]?.getBoundingClientRect().height || 0;
      const totalHeight = checkboxGroupRef.current.scrollHeight;
      if (totalHeight <= rowHeight * minRows) {
        setShowExpandBtn(false);
        setExpand(true);
      } else {
        setShowExpandBtn(true);
        setExpand(false);
      }
    }
  }, [minRows, checkboxProps.options])

问题

实际测试中发现了一个问题,当选项刚好占两行时,getBoundingClientRect 取到的 rowHeight 的实际值时 19.3515625px,而总高度通过 scrollHeight 取到的是 39px,两者十分接近,但是却因为刚好在我的期望值之外产生了bug,导致刚好两行时也出现了展开按钮。

解决

查阅资料定位到问题是浏览器会对小数的像素值做四舍五入,所以通过 scrollHeight 取到的 39px 正是 19.3515625px * 2 四舍五入后的结果。那么解决方式也就呼之欲出了

if (totalHeight <= Math.round(rowHeight * minRows))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions