You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何实现两行文本自动省略截断(适配可变宽度容器)

React 实现自适应宽度的两行文本省略截断

方案一:CSS原生实现(推荐,自适应容器宽度)

现代浏览器支持通过CSS属性直接实现多行省略,无需计算文本长度,完全适配容器的动态宽度。核心依赖-webkit-line-clamp属性,配合盒模型属性实现截断。

import React from 'react';

const TwoLineTruncatedText = ({ text }) => {
  return (
    <div style={{
      display: '-webkit-box',
      WebkitLineClamp: 2, // 指定显示行数
      WebkitBoxOrient: 'vertical',
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      // 可选:自定义内边距、行高
      lineHeight: '1.5em',
      padding: '0 8px',
    }}>
      {text}
    </div>
  );
};

export default TwoLineTruncatedText;

兼容性:Chrome、Firefox 68+、Safari、Edge等现代浏览器均支持,无需额外逻辑,容器宽度变化时会自动调整截断范围。


方案二:JavaScript动态计算(兼容旧浏览器)

针对不支持-webkit-line-clamp的环境(如IE),可以通过动态计算文本高度实现自适应截断。核心思路是用隐藏容器模拟真实容器的布局,判断文本是否超出两行高度,再通过二分法高效截断文本。

import React, { useState, useEffect, useRef } from 'react';

const TwoLineTruncatedText = ({ text, baseFontSize = 16, lineHeight = 1.5 }) => {
  const [truncatedText, setTruncatedText] = useState(text);
  const displayRef = useRef(null);
  const hiddenRef = useRef(null);

  useEffect(() => {
    const truncateText = () => {
      if (!displayRef.current || !hiddenRef.current) return;

      // 同步隐藏容器与显示容器的宽度、行高
      const containerWidth = displayRef.current.offsetWidth;
      hiddenRef.current.style.width = `${containerWidth}px`;
      hiddenRef.current.style.lineHeight = `${lineHeight}em`;
      hiddenRef.current.style.fontSize = `${baseFontSize}px`;
      hiddenRef.current.textContent = text;

      // 计算两行文本的最大允许高度
      const maxHeight = baseFontSize * lineHeight * 2;
      if (hiddenRef.current.offsetHeight <= maxHeight) {
        setTruncatedText(text);
        return;
      }

      // 二分法查找可显示的最长文本长度
      let left = 0;
      let right = text.length;
      let validLength = 0;

      while (left <= right) {
        const mid = Math.floor((left + right) / 2);
        const testText = text.slice(0, mid) + '...';
        hiddenRef.current.textContent = testText;

        if (hiddenRef.current.offsetHeight <= maxHeight) {
          validLength = mid;
          left = mid + 1;
        } else {
          right = mid - 1;
        }
      }

      setTruncatedText(text.slice(0, validLength) + '...');
    };

    truncateText();
    // 监听窗口 resize 或容器宽度变化,重新计算截断
    window.addEventListener('resize', truncateText);
    return () => window.removeEventListener('resize', truncateText);
  }, [text, baseFontSize, lineHeight]);

  return (
    <>
      <div
        ref={displayRef}
        style={{
          lineHeight: `${lineHeight}em`,
          fontSize: `${baseFontSize}px`,
          overflow: 'hidden',
          padding: '0 8px',
        }}
      >
        {truncatedText}
      </div>
      {/* 用于计算的隐藏容器,不占用页面空间 */}
      <div
        ref={hiddenRef}
        style={{
          position: 'absolute',
          visibility: 'hidden',
          whiteSpace: 'normal',
          left: '-9999px',
          top: 0,
          margin: 0,
          border: 'none',
          padding: 0,
        }}
      />
    </>
  );
};

export default TwoLineTruncatedText;

注意事项:

  • 需要根据实际场景调整baseFontSize和lineHeight参数,确保高度计算准确
  • 二分法比逐字符截断效率更高,适合长文本场景
  • 若容器宽度受父组件布局影响而非窗口resize,可额外监听父容器的尺寸变化事件

内容的提问来源于stack exchange,提问作者Bian Artola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:55:21