324

The following code can be found in this live example

I've got the following react native element:

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
} = React;

var SampleApp = React.createClass({
  render: function() {
    return      (
  <View style={styles.container}>

        <View style={styles.descriptionContainerVer}>
          <View style={styles.descriptionContainerHor}>
            <Text style={styles.descriptionText} numberOfLines={5} >
              Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
            </Text>
          </View>
        </View>

        <View style={styles.descriptionContainerVer2}>
          <View style={styles.descriptionContainerHor}>
            <Text style={styles.descriptionText} numberOfLines={5} >Some other long text which you can still do nothing about.. Off the screen we go then.</Text>
          </View>
        </View>



  </View>);
  }
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);

with the following styles:

var styles = StyleSheet.create({
  container:{
        flex:1,
    flexDirection:'column',
        justifyContent: 'flex-start',
        backgroundColor: 'grey'
    },
    descriptionContainerVer:{
    flex:0.5, //height (according to its parent)
    flexDirection: 'column', //its children will be in a row
    alignItems: 'center',
    backgroundColor: 'blue',
    // alignSelf: 'center',
  },
  descriptionContainerVer2:{
    flex:0.5, //height (according to its parent)
    flexDirection: 'column', //its children will be in a row
    alignItems: 'center',
    backgroundColor: 'orange',
    // alignSelf: 'center',
  },
  descriptionContainerHor:{
    //width: 200, //I DON\'T want this line here, because I need to support many screen sizes
    flex: 0.3,  //width (according to its parent)
    flexDirection: 'column',    //its children will be in a column
    alignItems: 'center', //align items according to this parent (like setting self align on each item)
    justifyContent: 'center',
    flexWrap: 'wrap'
  },
  descriptionText: {
    backgroundColor: 'green',//Colors.transparentColor,
    fontSize: 16,
    color: 'white',
    textAlign: 'center',
    flexWrap: 'wrap'
  }
});

This results in the following screen:

Text off screen app

How can I stop the text from going off the screen and keep it confined in the middle of the screen with a width of i.e. 80% of the parent.

I don't think I should use width because I will be running this on MANY different mobile screens and I want it to be dynamic, so I think I should rely totally on flexbox.

(That was the initial reason why I had flex: 0.8 within the descriptionContainerHor.

What I want to achieve is something like this:

What I want to achieve

Thank you!

28 Answers 28

528

I found solution from below link.

[Text] Text doesn't wrap #1438

<View style={{flexDirection:'row'}}> 
   <Text style={{flex: 1, flexWrap: 'wrap'}}> You miss fdddddd dddddddd 
     You miss fdd
   </Text>
</View>

Output

Below is the Github profile user link if you want to thank him.

Ally Rippley


Edit: Tue Apr 09 2019

As @sudoPlz mentioned in comments it works with flexShrink: 1 updating this answer.

enter image description here

8
  • 2
    Thanks, that's a great answer, but I've tried it and for some reason it doesn't always work ( no idea why :S). flexWrap is a bit flaky in react-native. +1 though for bringing that up.
    – SudoPlz
    Commented Jul 10, 2017 at 16:04
  • 1
    ^^^ This is the actual answer here. Accept this Op!
    – Greg Blass
    Commented Oct 26, 2017 at 17:13
  • 1
    Just note the info part of this answer github.com/facebook/react-native/issues/…
    – SudoPlz
    Commented Nov 6, 2017 at 20:55
  • 59
    I discovered that in some cases flexShrink: 1 applied to the parent view will help too.
    – SudoPlz
    Commented Apr 8, 2019 at 17:09
  • 1
    flexShrink: 1, then some padding to the Text and that does the job Commented Jul 13, 2021 at 17:43
254

The solution to that issue is flexShrink: 1.

<View
    style={{ flexDirection: 'row' }}
> 
   <Text style={{ flexShrink: 1 }}>
       Really really long text...
   </Text>
</View>

Depending on your set up, you may also also need to add flexShrink: 1 to the <View>'s parent as well, to get this to work, so play with that and you'll make it.

The solution was discovered by Adam Pietrasiak in this thread.

2
  • 5
    Parent view was also the solution for me! If parent had flexDirection: 'column', text refused to wrap. Commented Jan 28, 2020 at 16:39
  • flexShrink: 1 allows the Text component to take only the space it needs and expand to a max of its parent's width. This is perfect if you are adding a background colour to the Text component.
    – Sufian
    Commented 2 days ago
117

This is a known bug. flexWrap: 'wrap' didn't work for me but this solution seems to work for most people

Code

<View style={styles.container}>
    <Text>Some text</Text>
</View>

Styles

export default StyleSheet.create({
    container: {
        width: 0,
        flexGrow: 1,
        flex: 1,
    }
});
3
  • 4
    just took me the day to found your answer...Thanks! Commented Mar 11, 2019 at 17:07
  • My android emulator was freezing for good when the single line text was going out of bonds. It was a terrible bug to find and to fix (this not-so related SO question was the only thing I found). This seems to have fixed it, a container with {flexGrow: 1, flex: 1} and the text with {flex: 1}. Commented Feb 3, 2021 at 21:57
  • this works for me on "react-native": "0.68.2" Commented Jun 8, 2022 at 17:14
60

you just need to have a wrapper for your <Text> with flex like below;

<View style={{ flex: 1 }}>
  <Text>Your Text</Text>
</View>
5
  • 2
    Thats the only proper solution which actually works as well
    – Undefined
    Commented Aug 17, 2019 at 12:39
  • 3
    Indeed, flex: 1 is all you need.
    – instanceof
    Commented Sep 12, 2019 at 11:18
  • What if you don't want your text to occupy all the available space ?
    – huseyin39
    Commented Sep 25, 2020 at 14:17
  • Only <Text style={{ flex: 1 }}> without the additional <View> works as well for me.
    – sihaya
    Commented Oct 3, 2020 at 11:44
  • This worked for me with big texts. With small texts, tough, it added spaces. flexShrink: 1 solved it for me in both cases. Commented Jul 21, 2023 at 19:23
47

This worked for me

<View style={{flexShrink:1}}>
  <Text>some long random text...</Text>
</View>
2
  • i have complex structure, for some reason, this works, other answer does not haha
    – Vortechron
    Commented Mar 24, 2023 at 8:34
  • On all of the solutions, this one only worked for me
    – John
    Commented Jul 12, 2023 at 11:40
45

Most of the times, we see this problem when using flexDirection: 'row' because in other case, it is handled properly.

Anyway, here are the two ways to wrap the text properly;

FIRST METHOD:

To wrap the text to next line and not leave the display, we can do so by restricting the width of the <Text>;

<Text style={{width: "60%"}}>some long text goes here ...</Text>

The above code will restrict the width of the text to 60% of the available width and if the whole text doesn't fit in that, it will wrap itself, i.e, remaining text will move to next line and so on.

SECOND METHOD

set flexShrink: 1 on both text element as well as its parent element which is wrapping it.

e.g,

<View style={{ flexShrink: 1, justifyContent: 'space-between', alignItems: 'center', flex: 1, flexDirection: 'row'}}>
    <Text>First long string which goes long....</Text>
    <Text style={{flexShrink: 1}}>This is a long long text which must go out of the screen if we dont style it properly and not do some logic here</Text>
</View>

Other styles are just to show that result is working properly. flexShrink: 1 is the only thing which you need.

1
  • 1
    Adding flexShrink: 1 for Text component worked for me. Thanks Commented Jun 14 at 9:23
14

Another solution that I found to this issue is by wrapping the Text inside a View. Also set the style of the View to flex: 1.

14

It works if you remove flexDirection: row from descriptionContainerVer and descriptionContainerVer2 respectively.

UPDATE (see comments)

I made a few changes to achieve what I think you're after. First of all I removed the descriptionContainerHor component. Then I set the flexDirection of the vertical views to row and added alignItems: 'center' and justifyContent: 'center'. Since the vertical views are now in fact stacked along the horizontal axis I removed the Ver part from the name.

So now you have a wrapper view that should vertically and horizontally align it's content and stack it along the x-axis. I then simply put two invisible View components on the left and right side of the Text component to do the padding.

Like this:

<View style={styles.descriptionContainer}>
  <View style={styles.padding}/>
    <Text style={styles.descriptionText} numberOfLines={5} >
      Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
    </Text>
  <View style={styles.padding}/>
</View>

And this:

descriptionContainer:{
  flex:0.5, //height (according to its parent),
  flexDirection: 'row',
  backgroundColor: 'blue',
  alignItems: 'center',
  justifyContent: 'center',
  // alignSelf: 'center',
},
padding: {
  flex: 0.1
},
descriptionText: {
  backgroundColor: 'green',//Colors.transparentColor,
  fontSize: 16,
  flex: 0.8,
  color: 'white',
  textAlign: 'center',
  flexWrap: 'wrap'
},

Then you get what I believe you were after.

FURTHER IMPROVEMENTS

Now if you would like to stack multiple text areas within the blue and orange views you can do something like this:

<View style={styles.descriptionContainer2}>
  <View style={styles.padding}/>
  <View style={styles.textWrap}>
    <Text style={styles.descriptionText} numberOfLines={5} >
      Some other long text which you can still do nothing about.. Off the screen we go then.
    </Text>
    <Text style={styles.descriptionText} numberOfLines={5} >
      Another column of text.
    </Text>
  </View>
  <View style={styles.padding}/>
</View>

Where textWrapis styled like this:

textWrap: {
  flexDirection: 'column',
  flex: 0.8
},

Hope this helps!

4
  • Ok I changed the question a bit to reflect what I really wish to achieve. Now about the answer: The reason I used flexDirection: row was because (if I have this right in my head) flexDirection dictates the direction that the 'children' of that parent will be stacked at. Now I wanted the text to be the middle child in a parent that stacks children in a row, and occupy the 80% of the parents width (something like the second photo). Could you please update the answer a bit to reflect that? I'm willing to accept this as the answer.
    – SudoPlz
    Commented Mar 30, 2016 at 12:46
  • Sorry for the late reply, been busy. But I've updated my answer, hope this is what you needed.
    – Eysi
    Commented Mar 31, 2016 at 22:45
  • This answer is ABSOLUTELY amazing.. Exactly what I've been looking for, thanks Elliot !!!!!
    – SudoPlz
    Commented Mar 31, 2016 at 22:54
  • flexDirection: "row" was the core of my problem, tried everything else without luck. Change your flexDirection to column and the text inside it will wrap normally.
    – eightyfive
    Commented Dec 11, 2018 at 9:56
14

I had this same issue and to fix it I had to make sure ALL View parents had style={{flex: 1}}

1
  • 1
    This is the answer your looking for.
    – BennKingy
    Commented Oct 12, 2023 at 10:57
12
<View style={{flexDirection:'row'}}> 
  <Text style={{flex: 1, flexWrap: 'wrap'}}> 

This will work

1
  • Flexwrap is unnecessary. Commented Aug 21, 2021 at 19:42
10

I tried many of the answers above but none worked for me. I achieved the best result by putting flexShrink on the Text element itself and flexGrow on both the parent View and the Text element.

I needed flexDirection: row on the parent because I want to have an icon on the right

<View style={flexDirection: 'row', flexGrow: 1}>
    <Text style={
        flexGrow: 1, 
        flexShrink: 1, 
        paddingLeft: 16,
        paddingRight: 8,
        alignItems: 'center',
    }>
        A long text that needs to wrap into multiple lines
    </Text>
</View>
<Image source={rightArrow}/>

It looks like this:

Screenshot of text wrapping into multipple lines

4

In version 0.62.2 of React Native, i just put "flex-shrink: 1" in Container of my "Text", but remember the flex-direction:row in View of container. Thank you guys for the help.

My code:

export const Product = styled.View`
  background: #fff;
  padding: 15px 10px;
  border-radius: 5px;
  margin: 5px;
  flex-direction: row;
`;

export const ProductTitleContainer = styled.View`
  font-size: 16px;
  margin-left: 5px;
  flex-shrink: 1;
`;

export const ProductTitle = styled.Text`
  font-size: 16px;
  flex-wrap: wrap;
`;
`;
4

I wanted to add that I was having the same issue and flexWrap, flex:1 (in the text components), nothing flex was working for me.

Eventually, I set the width of my text components' wrapper to the width of the device and the text started wrapping. const win = Dimensions.get('window');

<View style={{
  flex: 1,
  flexDirection: 'column',
  justifyContent: 'center',
  alignSelf: 'center',
  width: win.width
}}>
  <Text style={{ top: 0, alignSelf: 'center' }} >{image.title}</Text>
  <Text style={{ alignSelf: 'center' }}>{image.description}</Text>
</View>
0
2

Use height: 'auto' in text style.

enter image description here enter image description here

2

I think you can do something like this, I have attached a picture with code for a better idea:

enter image description here

So, we can do something like this:

TermsOfService = {
  fontFamily: 'Verlag-Book';
  fontSize: 14px;
  textAlign: center;
},
HighlightedText = {
  font-family: 'Verlag-Book';
  font-size: 14px;
  text-align: center;
  color: ${COLORS.PRIMARY_ADMIRAL_BLUE};
},
Container: {
  width: 100%;
  alignSelf: center;
  alignItems: center;
  justifyContent: center;
  flexDirection: row;
  flexWrap: wrap;
}

And is your Component just use it like this:

 <View style={Container}>
   <Text style={TermsOfService}>By joining, you agree to the some thing </Text>
   <Text style={HighlightedText}>this is highlighted </Text>
   <Text style={TermsOfService}>and </Text>
   <Text style={HighlightedText}>and this as well</Text>
 </View>
1
<View style={{flexDirection:'row'}}> 
   <Text style={{ flex: number }}> You miss fdddddd dddddddd 
     You miss fdd
   </Text>
</View>

{ flex: aNumber } is all you need!

Just set 'flex' to a number that suit for you. And then the text will wrap.

1
  • Strangely enough this actually was the fix that worked for me.
    – Dror Bar
    Commented Mar 10, 2019 at 13:43
1

Non of the answers work for me, so I decided to use a hack, which is to split the text by whitespace and render each of the word separately.

Although it's a hack, the upside is that I don't have to worry so much about messing up the wrapping due to the parent's container style.

// This code is written in Typescript
import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
const styles = StyleSheet.create({
  container: {
    display: 'flex',
    flexWrap: 'wrap',
    flexDirection: 'row',
    flex: 1,
    justifyContent: 'center',
    paddingVertical: 8,
  },
})

export const WrapText: React.FC<{
  text: string
}> = ({ text }) => {
  return (
    <View style={styles.container}>
      {text.split(' ').map((word, index) => (
          <Text key={index}>
            {word}{' '}
          </Text>
        ))}
    </View>
  )
}

const Example = <WrapText text="Hello this is a working hack that wraps your text."/>

P/S: Of course this only works for alphabetical writing systems, other writing systems that does not utilise spaces (e.g. Chinese writings) will not wrap using this component.

1

Unfortunately none of the above worked for me.

I found this npm package you could use the package directly: https://github.com/Bang9/react-native-wrapped-text

Or create something similar like this:

<View style={{ alignItems: "center", alignSelf: "center", width: "100%" }}>
  <View style={{ flexDirection: "row", flexWrap: "wrap"}}>
    <Text style={{ textAlign: "center"}}>Long text, sooo looong...</Text>
  </View>
</View>

Based on : https://github.com/Bang9/react-native-wrapped-text/blob/master/src/index.js

1

Tried everything nothing worked but this ->

wrapText:{
    width:"65%"
},
listItemLeft:{
    fontWeight:"bold",
    margin:3
},

<View style={styles.wrapText}>
    <Text style={styles.listItemLeft}>{item.left}</Text>
</View>
0
<SafeAreaView style={{flex:1}}>
  <View style={{alignItems:'center'}}>
    <Text style={{ textAlign:'center' }}>
      This code will make your text centered even when there is a line-break
    </Text>
  </View>
</SafeAreaView>
1
  • 2
    Please comment your code and explain your answer Commented Jan 22, 2021 at 17:20
0

I came here as I was searching for a solution to break / wrap words that are very long. I found a solution and that is to use 'wordBreak' prop inside <Text's 'style' prop. Using wordBreak:break-word solved my problem.

0

Text overflowing code:

<View className="flex-row rounded-xl items-center p-2 pl-3 bg-red-400/20 space-x-2">
  <OrangeCircleIcon className="w-10 h-10" />
  <CText className="font-app-bold opacity-80">
    This is a Free Trial so you will not get charged anything now
  </CText>
</View>

Text not overflowing container code:

<View className="flex-row rounded-xl items-center p-2 pl-3 bg-red-400/20 space-x-2">
  <OrangeCircleIcon className="w-10 h-10" />
  <View className="flex-1"> {/* 👈🏻 Notice this addition */}
    <CText className="font-app-bold opacity-80">
      This is a Free Trial so you will not get charged anything now
    </CText>
  </View>
</View>

0

For a more sustainable approach for your app, use a component to render special texts that needs to be wrapped

// WrappedText.js Component
import { SafeAreaView, StyleSheet, Text } from "react-native";

const WrappedText = (props) => {
  const { children, textWrapperStyle={}, longTextStyle={} } = props;

  return (
    <SafeAreaView style={[styles.textWrapper, textWrapperStyle]}>
      <Text style={[styles.longText, longTextStyle]}>{children}</Text>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  textWrapper: { flexDirection: "row" },
  longText: {
    flex: 1,
    flexWrap: "wrap",
  },
});

export default WrappedText;

Usage of component anywhere

<WrappedText longTextStyle={{ color: "blue" }}>{longText}</WrappedText>
1
  • I thought SafeAreaView is supposed to be used as a (full screen) parent view. What if that text is not a child of a full screen component? I would imagine that to look weird and not behave properly.
    – SudoPlz
    Commented Feb 5 at 15:13
0

I found an easy way inspired by the solution here which works on Web and native mobile.

  <View style={{ flexDirection: "row" }}>
    <Text style={{ flex: 1 }>"Replace it with a long message"</Text>
  </View>

Furthermore, you can increase the font size and do more required tuning. Just make sure not to directly set the height property on your .

  <View style={{ flexDirection: "row" }}>
    <Text style={{ flex: 1, fontSize: 18, lineHeight: 40 }>"Replace it with a long message"</Text>
  </View>
0

I had the same problem but also needed bullet points for an unordered list.

This worked for me:

<View style={{flexDirection: 'row', marginVertical: '4%'}}>
    <Text>•</Text><Text style={{ paddingLeft: 10, paddingRight: 10 }}>A really really really long line of text...</Text>
</View>

For TailwindsCSS this worked too:

<View className="flex-row my-[4%]">
    <Text>•</Text><Text className="px-3">A really really really long line of text...</Text>
</View>
0

This is what fixed it for me using nowrap. it strange how wrap doesnt work in here

<View style={{flexWrap: 'nowrap', flexGrow: 1, flex: 1}}>
  <Text>Text goes here</Text>
</view>
-1

my solution below:

<View style={style.aboutContent}>
     <Text style={[styles.text,{textAlign:'justify'}]}>
        // text here                            
     </Text>
</View>

style:

aboutContent:{
    flex:8,
    width:widthDevice-40,
    alignItems:'center'
},
text:{
    fontSize:widthDevice*0.04,
    color:'#fff',
    fontFamily:'SairaSemiCondensed-Medium'
},

result: [d]my result[1]

1
  • So you're using a static width on the parent, which is exactly what we wanted to avoid here.
    – SudoPlz
    Commented Jul 17, 2018 at 22:02
-4

try to use this prop adjustsFontSizeToFit={true} in text component like this.

<Text adjustsFontSizeToFit={true}>
1
  • this makes the text size smaller, it doesn't wrap the text, which is what was the intention of the question.
    – SudoPlz
    Commented Feb 22, 2022 at 17:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.