MUI:根据渲染宽度动态切换文本内容
根据元素渲染尺寸切换文本内容(React + Material UI 5)
针对你需要根据元素实际渲染空间切换文本的需求,以下是几种实用的实现方案:
方案一:使用ResizeObserver监听元素尺寸(最精准)
这种方法直接监听目标元素的实际渲染宽度,能精准应对字体、字间距、容器布局等因素带来的尺寸变化,完全贴合你的需求。
实现代码(TypeScript)
import { useState, useRef, useEffect } from 'react'; import { Typography } from '@mui/material'; const ResponsiveName = () => { const [displayText, setDisplayText] = useState<string>('William Jefferson Clinton'); const textRef = useRef<HTMLDivElement>(null); useEffect(() => { const observer = new ResizeObserver((entries) => { const { width } = entries[0].contentRect; // 根据实际测试调整阈值 if (width < 80) { setDisplayText('42'); } else if (width < 150) { setDisplayText('Bill Clinton'); } else { setDisplayText('William Jefferson Clinton'); } }); textRef.current && observer.observe(textRef.current); return () => { textRef.current && observer.unobserve(textRef.current); }; }, []); return ( <Typography ref={textRef} variant="body1"> {displayText} </Typography> ); }; export default ResponsiveName;
说明
- 代码中
80px、150px是示例阈值,建议在浏览器调试工具中,根据你的字体样式、字间距实际测试调整数值。 - ResizeObserver是浏览器原生API,无需额外依赖,性能表现稳定。
方案二:利用CSS容器查询(MUI 5.10+支持)
如果你的Material UI版本在5.10及以上,可以使用容器查询实现纯CSS控制,无需编写JS监听逻辑,更轻量化。
实现代码
import { Box, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; // 启用容器查询的父容器 const TextContainer = styled(Box)(({ theme }) => ({ containerType: 'inline-size', display: 'inline-block', })); // 不同尺寸下的文本组件 const FullName = styled(Typography)(({ theme }) => ({ display: 'block', [theme.breakpoints.up('container(150px)')]: { display: 'none', }, })); const ShortName = styled(Typography)(({ theme }) => ({ display: 'none', [theme.breakpoints.between('80px', '150px')]: { display: 'block', }, })); const NumberText = styled(Typography)(({ theme }) => ({ display: 'none', [theme.breakpoints.down('container(80px)')]: { display: 'block', }, })); const ResponsiveName = () => { return ( <TextContainer> <FullName variant="body1">William Jefferson Clinton</FullName> <ShortName variant="body1">Bill Clinton</ShortName> <NumberText variant="body1">42</NumberText> </TextContainer> ); }; export default ResponsiveName;
说明
- 容器查询基于父容器的宽度而非视口宽度,刚好匹配元素自身空间的需求。
- 同样需要根据实际样式调整容器宽度阈值。
方案三:视口级媒体查询(仅适合全屏布局场景)
如果你的文本元素宽度完全由屏幕视口决定,而非容器限制,可以使用MUI内置的媒体查询工具:
实现代码
import { Typography, useTheme, useMediaQuery } from '@mui/material'; const ResponsiveName = () => { const theme = useTheme(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); const isMediumScreen = useMediaQuery(theme.breakpoints.between('sm', 'md')); let displayText = 'William Jefferson Clinton'; if (isMediumScreen) { displayText = 'Bill Clinton'; } else if (isSmallScreen) { displayText = '42'; } return <Typography variant="body1">{displayText}</Typography>; }; export default ResponsiveName;
说明
- 这种方法依赖屏幕视口尺寸,无法应对元素被容器限制宽度的场景,仅适合全屏布局的简单场景。
内容的提问来源于stack exchange,提问作者mateoc15
相关产品推荐
相关产品推荐

