banner
innei

innei

写代码是因为爱,写到世界充满爱!
github
telegram
twitter

CSS Text Overflow Clip does not cut half a character.

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.

The text behind is truncated

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.

image

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.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.