
本文介绍一种纯 css + react 状态驱动的多行文本折叠方案,无需第三方库,兼容 next.js,支持按行数精确截断并显示“read more”按钮,点击后平滑展开全文。
本文介绍一种纯 css + react 状态驱动的多行文本折叠方案,无需第三方库,兼容 next.js,支持按行数精确截断并显示“read more”按钮,点击后平滑展开全文。
在 Next.js 项目中实现「指定行数内显示、超出则折叠 + Read more 展开」效果,关键在于避免依赖 text-overflow: ellipsis(仅支持单行),转而采用 max-height + overflow: hidden 配合 CSS 过渡实现可控折叠。以下是完整、可复用的实现方案:
✅ 推荐实现:基于高度控制的响应式折叠组件
// components/CollapsibleText.tsx
'use client';
import { useState } from 'react';
interface CollapsibleTextProps {
children: string;
lines?: number; // 期望显示的行数(默认 3 行)
className?: string;
}
export default function CollapsibleText({
children,
lines = 3,
className = '',
}: CollapsibleTextProps) {
const [expanded, setExpanded] = useState(false);
// 根据字体大小和行高估算 max-height(单位 px)
// 假设 font-size: 16px, line-height: 1.5 → 每行 ≈ 24px
const lineHeightPx = 24;
const collapsedHeight = lines * lineHeightPx;
return (
<div classname="relative">
<p classname="{`transition-all" duration-300 ease-in-out overflow-hidden expanded : style="{{" maxheight:>
{children}
</p>
{children.length > 100 && ( // 简单长度阈值判断是否需要折叠
<button onclick="{()"> setExpanded(!expanded)}
className="mt-2 text-sm text-blue-600 hover:underline focus:outline-none"
aria-expanded={expanded}
aria-controls="collapsible-content"
>
{expanded ? 'Read less' : 'Read more'}
</button>
)}
</div>
);
}
? 使用方式(Next.js App Router)
// app/page.tsx
import CollapsibleText from '@/components/CollapsibleText';
export default function HomePage() {
const longText = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.`;
return (
<article classname="p-6 max-w-2xl mx-auto"><h2 classname="text-xl font-bold mb-4">Product Description</h2>
<collapsibletext lines="{3}">
{longText}
</collapsibletext></article>
);
}
⚠️ 注意事项与优化建议
- 行高一致性:确保 .collapsible_text 所在元素的 font-size 和 line-height 固定(推荐使用 rem 或 px),否则 max-height 计算会失准;
- 无障碍友好:添加 aria-expanded 和语义化
- 性能优化:避免在服务端渲染(SSR)中使用 useState —— 此组件需标记为 'use client';
- 平滑过渡增强:若需更自然的展开动画,可配合 height: auto + getBoundingClientRect() 动态计算目标高度(进阶场景);
- 移动端适配:可通过媒体查询动态调整 lines 值(如 lines={window.innerWidth
该方案轻量、稳定、无依赖,完美契合 Next.js 的现代 React 开发范式,同时兼顾视觉精度与用户体验。










