React组件中用CSS实现文本溢出显示省略号(含无空格场景)
解决React组件中文本省略与展开不影响布局的问题
一、让无空格文本超出容器显示省略号
你现在的代码里只加了textOverflow: 'ellipsis',但这个属性单独用不会生效,必须配合另外两个CSS属性,还要给文本容器加宽度限制(块级元素默认占满父容器,没宽度限制不会触发溢出)。针对无空格长文本,需要给文本容器设置以下样式:
{ whiteSpace: 'nowrap', /* 强制文本不换行 */ overflow: 'hidden', /* 隐藏超出部分 */ textOverflow: 'ellipsis', /* 用省略号替代隐藏内容 */ flex: 1, /* 在flex布局里让文本占满剩余空间,和右侧图标不挤在一起 */ minWidth: 0 /* 解决flex子元素因内容过长不收缩的问题,确保宽度限制生效 */ }
二、保证文本展开不影响兄弟组件布局
你用Material-UI Tooltip的思路完全正确,因为Tooltip默认是绝对定位的,脱离正常文档流,不会占用兄弟组件的布局空间,也不会推动其他元素。只要别把Tooltip的定位改成relative或static就行。
修改后的完整代码
把原来的文本容器样式替换掉,其他部分保持不变:
import React from 'react' import Tooltip from '@material-ui/core/Tooltip' import Typography from '@material-ui/core/Typography' import { makeStyles, createStyles, withStyles } from '@material-ui/core/styles' import { Divider } from '@material-ui/core' import { Paper } from '@material-ui/core' import { ErrorOutlineOutlinedIcon } from '../../icon' const HtmlTooltip = withStyles(theme => ({ arrow: { '&::before': { color: 'white' } }, tooltip: { backgroundColor: '#f5f5f9', boxShadow: theme.shadows[8], color: 'rgba(0, 0, 0, 0.87)', fontSize: 14, maxWidth: 800, padding: 0, }, tooltipPlacementTop: { margin: '4px 0', }, }))(Tooltip) const imageStyles = { root: { color: 'deeppink', height: 20, marginBottom: 0, width: 20 } } const Image = withStyles(imageStyles)(({ classes }) => ( <ErrorOutlineOutlinedIcon classes={classes} /> )) const useStyles = makeStyles(theme => createStyles({ content: { border: `1px solid ${theme.palette.grey[300]}`, margin: 0, minWidth: 600, padding: 0, zIndex: 1, }, contentInner: { padding: theme.spacing(1) }, header: { backgroundColor: 'deeppink', fontWeight: 'bold', padding: theme.spacing(1), } }) ) export default function CustomTooltip(params) { const classes = useStyles() const action = [ { content: '<pre>Check Delhi in India or not</pre>', name: 'Check Delhi in India or not', value: <pre>Check Delhi in India or not</pre> } ] const textDispaly = action.some(c => c.content === params.value) ? action.find(c => c.content === params.value).value : params.value const labelDisplay = action.some(c => c.content === params.value) ? action.find(c => c.content === params.value).name : params.value return ( <> {labelDisplay && labelDisplay.length > 20 ? ( <HtmlTooltip arrow interactive title={ <Paper className={classes.content}> <div className={classes.header}> <Typography color='inherit' variant='body1' style={{color: 'white', fontSize: '16px'}}> {params.column.colDef.headerName} </Typography> </div> <Divider /> <div className={classes.contentInner}> {textDispaly} </div> </Paper> } placement='top' > <div style={{ alignItems: 'center', display: 'flex', fontSize: '14px', justifyContent: 'space-between' }}> {/* 修改后的文本容器样式 */} <div style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>{labelDisplay}</div> <Image/> </div> </HtmlTooltip> ) : ( <div style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>{labelDisplay}</div> )} </> ) }
补充说明
- 如果后续需要支持多行文本省略,可以用
-webkit-line-clamp属性,但单行省略用上面的方式最稳定。 - 你开启的
interactive属性能让用户和Tooltip内的内容交互,同时Tooltip的绝对定位不会干扰父容器和兄弟组件的布局,完全符合你的需求。
内容的提问来源于stack exchange,提问作者KARTHIKEYAN.A
相关产品推荐
相关产品推荐

