最近同事問我,CSS 能不能實現文本溢出截斷,但是不要把單個字符截斷。一般我們會用 text-overflow: clip; overflow: hidden
去實現這個。但是很多情況下都會出現這樣的情況。
我想了一下,好像不太行,要是我就用 JS 去算寬度,之後再去判斷應該顯示幾個完整的字了。如果做不到的,就只能和 UI 妥協了。
突然,我靈光一閃。如果在正常情況下文字的換行是怎麼樣的呢,正常的換行不會出現字被裁了半個的情況,而且還能根據標點去換行。
那麼,不是只要用其他方式去只顯示第一行不就行了嗎。所以只要給外面的容器加一個最大高度,高度是第一行文字的高度,然後去掉 white-space: nowrap;text-overflow: clip;
就大功告成了。
而且這樣寫,不管文字是啥都不會出現裁切半個的問題。至於文字容器高度的話,一般 UI 稿子上都有,直接複製就行了。這樣是最簡單的。兩行也沒問題。多少行都沒問題。
此方法同樣適用於 React Native。
上圖為 RN 0.69 的效果,上部分是使用此方法的效果,下部分是直接使用 clip 的效果。
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"
>
燕子去了,有再來的時候1111,,,,,,,,........;楊柳枯了,有再青的時候;桃花謝了,有再開的時候。但是,聰明的,你告訴我,我們的日子為什麼一去不復返呢?——是有人偷了他們罷:那是誰?又藏在何處呢?是他們自己逃走了罷:現在又到了哪裡呢?
</Text>
</View>
<View style={styles.padding}></View>
<View style={[styles.flexContainer, { height: 48 }]}>
<Text
ellipsizeMode="clip"
numberOfLines={2}
style={{ fontSize: 24, lineHeight: 24 }}
>
燕子去了,有再來的時候1111,,,,,,,,........;楊柳枯了,有再青的時候;桃花謝了,有再開的時候。但是,聰明的,你告訴我,我們的日子為什麼一去不復返呢?——是有人偷了他們罷:那是誰?又藏在何處呢?是他們自己逃走了罷:現在又到了哪裡呢?
</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, // 注意這個(必須指定)
},
container: {
flex: 1,
backgroundColor: '#fff',
},
padding: {
height: 80,
backgroundColor: '#12222233',
marginVertical: 12,
},
})
代碼已附上,注意 RN 的 Text 必須指定高度,否則會聽父元素的高度,就會不起作用,建議直接給設備高度。