Recently, a colleague asked me if CSS can truncate text overflow without cutting off individual characters. Usually, we would use text-overflow: clip; overflow: hidden
to achieve this. However, in many cases, this situation occurs.
I thought about it and it seems like it won't work. If it were me, I would calculate the width using JavaScript and then determine how many complete characters should be displayed. If it can't be done, then I can only compromise with the UI.
Suddenly, I had a flash of inspiration. What if we consider how normal line breaks work? Normal line breaks do not result in half-cut characters, and they can also break lines based on punctuation.
So, as long as we find a way to only display the first line, it should work. Therefore, we just need to add a maximum height to the outer container, where the height is the height of the first line of text, and remove white-space: nowrap; text-overflow: clip;
. Then we are done.
And by writing it this way, no matter what the text is, it will not be cut in half. As for the height of the text container, it is usually provided in the UI design, so we can just copy it. This is the simplest way. It works for two lines as well. It works for any number of lines.
This method also applies to React Native.
The image above shows the effect of RN 0.69. The top part shows the effect using this method, and the bottom part shows the effect using clip directly.
import { StatusBar } from 'expo-status-bar'
import { Dimensions, StyleSheet, Text, View } from 'react-native'
export default function App() {
return (
<View style={styles.container}>
<View style={styles.padding} />
<View>
<View style={styles.flexContainer}>
<Text
style={styles.text}
numberOfLines={4}
lineBreakMode="clip"
ellipsizeMode="clip"
>
The swallows have left, but they will come back again,,,,,,,,........; the willows have withered, but they will turn green again; the peach blossoms have fallen, but they will bloom again. However, tell me, why don't our days come back? —— Is it because someone stole them: who is it? Where are they hiding? Or did they run away by themselves: where are they now?
</Text>
</View>
<View style={styles.padding}></View>
<View style={[styles.flexContainer, { height: 48 }]}>
<Text
ellipsizeMode="clip"
numberOfLines={2}
style={{ fontSize: 24, lineHeight: 24 }}
>
The swallows have left, but they will come back again,,,,,,,,........; the willows have withered, but they will turn green again; the peach blossoms have fallen, but they will bloom again. However, tell me, why don't our days come back? —— Is it because someone stole them: who is it? Where are they hiding? Or did they run away by themselves: where are they now?
</Text>
</View>
</View>
<StatusBar style="auto" />
</View>
)
}
const styles = StyleSheet.create({
flexContainer: {
// width: 350,
// alignItems: 'flex-start',
// justifyContent: 'flex-start',
height: 46,
overflow: 'hidden',
},
text: {
fontSize: 24,
lineHeight: 24,
height: Dimensions.get('window').height, // Note this (must be specified)
},
container: {
flex: 1,
backgroundColor: '#fff',
},
padding: {
height: 80,
backgroundColor: '#12222233',
marginVertical: 12,
},
})
The code is attached. Note that the height of the Text component in RN must be specified, otherwise it will inherit the height of the parent element and won't work properly. It is recommended to directly specify the device height.