惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
IT之家
IT之家
博客园 - Franky
Stack Overflow Blog
Stack Overflow Blog
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
Engineering at Meta
Engineering at Meta
S
SegmentFault 最新的问题
V
Visual Studio Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
H
Help Net Security
V
V2EX
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
博客园 - 叶小钗
J
Java Code Geeks
博客园 - 【当耐特】
月光博客
月光博客
爱范儿
爱范儿
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件

博客园 - SKILL·NULL

获取指定 dom 的 touchmove 方向及到达边缘时是否禁止橡皮筋效果 如何通过传参来实现SVG排序图标的三种状态 如何为GIT设置全局勾子,为每次提交追加信息 一文了解大模型、小模型与各类神经网络的关系 如何在Mac上调整外星人鼠标AW720M的灯光颜色 Karabiner-Elements最常用配置 IndexedDB封装 echarts获取坐标上的点距离顶部底部高度 Let`s Encrypt 生成免费自动续签 HTTPS 证书 H5滚动截取长图 ReactNative常见问题及处理 根据.nvmrc自动切换项目所需node版本 Command PhaseScriptExecution failed with a nonzero exit code echarts双Y轴,实现均分为包含刻度0的指定段数,同时对齐刻度 env(safe-area-inset-bottom) 兼容写法 缩放实现0.5px 禁止 IOS 橡皮筋效果 JS 拦截浏览器返回 海康威视DS-IPC-E42H-IWPT监控画面竖线处理 Echarts 5 动态按需引入图表 React 18 自定义 Hook 获取 useState 最新值 处理报错 ResizeObserver loop completed with undelivered notifications.
如何实现超长数字:先缩小字号,再省略号
SKILL·NULL · 2026-08-11 · via 博客园 - SKILL·NULL
如何固定列宽下数字过长时:先继承父级字号,再按设计稿字号逐步 -1 缩小,最小 12;仍超出才 `...`。

适配约定(375 设计稿):

- `html.fontSize = (width / 375) * 100`
- postcss `rootValue: 100` → 设计稿 px 转 rem:`px / 100`

---

## 封装:AutoFitText

```tsx
import { useLayoutEffect, useRef, type ReactNode } from 'react'

/** 与 index.html / postcss-pxtorem 一致 */
const DESIGN_ROOT_VALUE = 100
const MIN_DESIGN_FONT_SIZE = 12

const designPxToRem = (designPx: number) =>
  `${designPx / DESIGN_ROOT_VALUE}rem`

interface AutoFitTextProps {
  children: ReactNode
  className?: string
}

/**
 * 默认 inherit;超出后设计稿字号逐步 -1,最小 12;仍超出再省略号。
 */
export const AutoFitText = ({ children, className }: AutoFitTextProps) => {
  const ref = useRef<HTMLSpanElement>(null)

  useLayoutEffect(() => {
    const el = ref.current
    if (!el) return

    const fit = () => {
      el.style.fontSize = ''
      el.classList.remove('is-ellipsis')

      if (el.clientWidth <= 0) return
      if (el.scrollWidth <= el.clientWidth + 1) return

      const rootPx =
        parseFloat(getComputedStyle(document.documentElement).fontSize) ||
        DESIGN_ROOT_VALUE
      const inheritedCssPx = parseFloat(getComputedStyle(el).fontSize) || 14
      let designSize = Math.round((inheritedCssPx / rootPx) * DESIGN_ROOT_VALUE)

      while (
        designSize > MIN_DESIGN_FONT_SIZE &&
        el.scrollWidth > el.clientWidth + 1
      ) {
        designSize -= 1
        el.style.fontSize = designPxToRem(designSize)
      }

      if (el.scrollWidth > el.clientWidth + 1) {
        el.classList.add('is-ellipsis')
      }
    }

    fit()
    window.addEventListener('resize', fit, false)
    return () => window.removeEventListener('resize', fit, false)
  }, [children])

  return (
    <span
      ref={ref}
      className={`auto-fit-text${className ? ` ${className}` : ''}`}
    >
      {children}
    </span>
  )
}
```

配套样式:

```less
.auto-fit-text {
  font-size: inherit;
  text-overflow: clip;

  &.is-ellipsis {
    text-overflow: ellipsis;
  }
}

/* 容器必须有固定宽度,文字节点占满宽度,才能正确测溢出 */
.demo-box {
  width: 120px;
  overflow: hidden;
  font-size: 16px;

  > span {
    display: block;
    width: 100%;
    max-width: 100%;
    overflow: hidden;
    white-space: nowrap;
  }
}
```

---

## 使用案例(独立 Demo)

```tsx
import { useState } from 'react'
import { AutoFitText } from './auto-fit-text'

export default function AutoFitTextDemo() {
  const [text, setText] = useState('12345678901234567890')

  return (
    <div>
      <input
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="输入一段文字试试"
      />

      {/* 固定 120px 宽,观察字号缩小 / 省略号 */}
      <div className="demo-box">
        <AutoFitText>{text}</AutoFitText>
      </div>
    </div>
  )
}
```

效果说明:

1. 输入较短内容:保持父级 `16px`
2. 内容变长:字号逐步降到 `15 → 14 → … → 12`
3. 到 `12` 仍放不下:显示 `...`

---

## 注意点

1. 父容器要有明确宽度,且 `overflow: hidden`
2. 文字节点 `width: 100%` + `white-space: nowrap`,否则 `scrollWidth === clientWidth` 测不准
3. 缩小后写 rem(`设计稿px / 100`),不要写死 `px`
4. 未缩小时清空内联 `fontSize`,继续继承父级字号