Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Text] Auto adjust font size to fit Text node width. #728

Closed
danscan opened this issue Apr 7, 2015 · 35 comments
Closed

[Text] Auto adjust font size to fit Text node width. #728

danscan opened this issue Apr 7, 2015 · 35 comments
Labels
Good first issue Interested in collaborating? Take a stab at fixing one of these issues. Resolution: Locked This issue was locked by the bot.

Comments

@danscan
Copy link
Contributor

danscan commented Apr 7, 2015

Hi! I'm looking for how I can achieve behavior similar to UILabel's adjustsFontSizeToFitWidth=true, but haven't been able to find anything.

Is this possible on a Text node?

@ide
Copy link
Contributor

ide commented Apr 7, 2015

+1, this is one of those things that native does much better than web and is really well-suited to shadow-thread computation

@brentvatne
Copy link
Collaborator

👍 would love to see this, @danscan can you try putting a PR together to add this in?

@MattFoley
Copy link

👍 me too.

@brentvatne
Copy link
Collaborator

@nicklockwood @sahrens - do you think this is desirable to include in core? any thoughts for an implementation strategy for this?

@nicklockwood
Copy link
Contributor

I'd be in favour of it. Interesting to consider how it would interact with flexbox though - perhaps it would only work if the width and height are set explicitly?

@MattFoley
Copy link

I'm very new to the JS side of things, but I'd assume that it would shrink rather than wrapping past a specified number of lines.

@danscan
Copy link
Contributor Author

danscan commented May 28, 2015

@MattFoley yes, much like the native behavior on UILabel, the font size would decrease to fit the width.

@brentvatne
Copy link
Collaborator

@nicklockwood - I think it would be ideal if it were to support flex as well - my guess, as someone who is not too deep in this part of the internals, is that we could perform text sizing after the layout pass has computed the container size. cc @ide

@ide
Copy link
Contributor

ide commented May 29, 2015

Here's a proposal for the API: there is an optional prop called numberOfLines. If this is set, the text shrinks itself until it can fit in that number of lines or fewer (also want a lower bound so we don't end up with illegibly small text), given the available space provided by its parent.

If numberOfLines is not set, then auto-shrinking behavior takes effect only if upper bounds on the width and height of the text component are known. Example scenarios:

  • Both width and height are set
  • Dimension along the main axis is set. Ex: height is set with flexDirection: 'column'. The upper bound of available space along the cross axis is known from the parent.
  • You could specify max-width/max-height instead of width/height in the cases above -- we care only about an upper bound on available space

In these scenarios, the text is allowed to wrap and it shrinks until all of the text can fit in the available space (and again, we have some lower bound so text doesn't become illegible).

And finally, numberOfLines may be combined with a bounded width/height as well.

@nicklockwood
Copy link
Contributor

We already have a numberOfLines property though…

@nicklockwood
Copy link
Contributor

Or are you proposing that we use the existing numberOfLines property, but augment its behavior to include shrinking the text as well as truncating it, with the min size defaulting to current size (no shrinking) unless otherwise specified?

@ide
Copy link
Contributor

ide commented May 29, 2015

@nicklockwood, exactly -- if the proposed adjustsFontSizeToFitWidth were set to true then the behavior you describe would take effect.

@brentvatne brentvatne changed the title Auto adjust font size to fit Text node width. [Text] Auto adjust font size to fit Text node width. May 31, 2015
@marcshilling
Copy link

+1 - definitely need this

@patrickomeara
Copy link
Contributor

+1 this would be great

@brentvatne
Copy link
Collaborator

If anyone is interested, I made a really simplistic version of this for now that just tests the width/height of text at various font sizes and chooses the best one: https://gist.github.com/brentvatne/a267d10eabd2d91a8d44

Use with caution ;)

A real implementation of it would be very welcome here

@brentvatne brentvatne added Good first issue Interested in collaborating? Take a stab at fixing one of these issues. Community Responsibility labels Jul 21, 2015
@danscan
Copy link
Contributor Author

danscan commented Jul 21, 2015

@brentvatne this is awesome!

@brentvatne
Copy link
Collaborator

@danscan - feel free to clean that up / improve it and publish it to npm if you like!

@MattFoley
Copy link

My goal is to get this implemented in the next few days on the ObjC side, and as a prop for Text, adjustsFontSizeToFitWidth.

@marcshilling
Copy link

This is still a big missing piece of React Native. Would love to get #4026 moving along...

@mkonicek
Copy link
Contributor

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out its new home: https://productpains.com/post/react-native/text-auto-adjust-font-size-to-fit-text-node-width

ProductPains helps the community prioritize the most important issues thanks to its voting feature.
It is easy to use - just login with GitHub. GitHub issues have voting too, nevertheless
Product Pains has been very useful in highlighting the top bugs and feature requests:
https://productpains.com/product/react-native?tab=top

Also, if this issue is a bug, please consider sending a pull request with a fix.
We're a small team and rely on the community for bug fixes of issues that don't affect fb apps.

@MattFoley
Copy link

@mkonicek If you're closing this out, what does that mean for the existing PR at #4026?

@greyvugrin
Copy link
Contributor

^ +1, this would be great to have, not sure how else to cope with varying text length in Android. Lmk if I'm missing something

@MattFoley
Copy link

It's been built on iOS, just needs an Android implementation added.

@DaniAkash
Copy link

responsiveFontSize from react-native-responsive-dimensions can automatically adjust fontSize based on the device's screen size.

@obykoo
Copy link

obykoo commented Mar 15, 2017

I would like to have also this, so I can define width: 50%, height: 50% and text can fill this on every screen..

@mobimation
Copy link

Or can one envision a "willWrap" event trigger where changing the font size in the handler have the rendering be recalculated instead of wrapping ?

@wmonecke
Copy link

wmonecke commented Sep 7, 2017

I managed to overcome this by doing the following.

  1. Pick the font size you like for the current view you have (Make sure it looks good for the current device you are using in the simulator).

  2. import { Dimensions } from 'react-native' and define the width outside of the component like so:
    let width = Dimensions.get('window').width;

  3. Now console.log(width) and write it down. If your good looking font size is 15 and your width is 360 for example, then take 360 and divide by 15 ( = 24). This is going to be the important value that is going to adjust to different sizes.

  4. Use this number in your styles object like so:

    textFontSize: { fontSize = width / 24 },...

Now you have a responsive fontSize.

@flikQ
Copy link

flikQ commented Sep 20, 2017

@wmonecke this is great but I would imagine most were already using this. I think the best way to explain what a lot of the people here want is a % size of the text/views parent. So in my card we are displaying Cards (trading cards) but they are pulled from one component, sometimes there are 3 in a row, someones 2 sometimes 1 taking up whole screen. Could even be 4 or 5.

The point is having a text size that is lets say 50% of the parent (overall card width) is more desirable than device width/height. By using dimensions the text size is the same even when you have 3 items in a row or 2 in a row, which provides inconsistent viewing.

@yoandypv
Copy link

Finally i found this solution that cut the text if is more large than screen size <Text adjustsFontSizeToFit numberOfLines={1} ....

@Viral-Inc
Copy link

how complicated is it to have adjustsFontSizeToFit work for Android too?

@hegelstad
Copy link

React-native should really solve this out-of-the-box.

@JulianKingman
Copy link

I came close to implementing this with the following workaround. Of course this would be exact if you used monospace fonts.

const letterToWidthRatio = 0.5476; // Approximate this by taking the width of some representative text samples
const text = "Some text to display";
const buffer = 5 // arbitrary amount to decrease font size, just in case
const fontSize = containerWidth / (text.length * letterToWidthRatio) - 5;
render() {
  return (
    <View style={{width: containerWidth}}>
      <Text style={{fontSize}}>{text}</Text>
    </View>
  )
}

@privateOmega
Copy link

@JulianKingman How did you approximate letterToWidthRatio? I require something of the sort with the problem I am currently trying to solve.

@JulianKingman
Copy link

@privateOmega compare the number of characters with the length, using onLayout

const text = “some example string”
<Text onLayout={({nativEvent: {layout}}) => {condole.log(text.length / layout.width)}}>{text}</Text>

Try a few different strings, and keep in mind punctuation will probably cause problems, so you may want to filter those out in your final font size calculation.

@bartoszwrobel
Copy link

bartoszwrobel commented Jun 12, 2018

What about this?
https://www.youtube.com/watch?v=JYrpEAz_A1U

I'm not sure that this is new functionality but the video is kinda new, so maybe this is worth to implement in React Native?

@facebook facebook locked as resolved and limited conversation to collaborators Jul 23, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Good first issue Interested in collaborating? Take a stab at fixing one of these issues. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests