63

Enlargement of size of the device font will sometimes break (Styling wise).

Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80
A-J-A
  • 2,344
  • 1
  • 17
  • 26
  • 1
    This is a bad choice because it hurts users with poor eyesight, and users with shaky hands or other motor issues that make it hard to interact with small touch targets. A better solution is to fix your styling so font changes don't break it. (For example, don't use fixed heights or widths.) – Aaron Brager Aug 17 '18 at 15:01
  • 4
    It's not always the case @AaronBrager, on small device its almost impossible to "fix" your styling to fit text on same row. So unless you don't have much text to view on your screen then yes you can be more considerate. So this is totally optional and not obligatory. What ever fits your need you do so. – A-J-A Aug 19 '18 at 11:45
  • 2
    It doesn’t have to be on the same row. Users who turn their font size all the way up are happy to have awkward text wrapping. – Aaron Brager Aug 19 '18 at 14:27
  • 2
    Well in case the project owner doesn't want their app to break like that they can use this. Else they can totally ignore this and keep the font on auto size. Again this is totally optional. @AaronBrager – A-J-A Aug 19 '18 at 14:39

9 Answers9

117

Disabling font scaling can hurt the accessibility of your app, ideally if you want to limit scaling for Apps using React native 0.58.0 and above; use the maxFontSizeMultiplier prop on specific Text components.

However if you absolutely want to disable font scaling across your entire Application, you can do so by globally setting the allowFontScaling prop in the defaultProps of Text.

You should place these lines in your root entrypoint (normally index.js) before AppRegistry.registerComponent.

For React Native 0.56.0+

Text.defaultProps = Text.defaultProps || {};
Text.defaultProps.allowFontScaling = false;

For earlier versions of React Native you should only need the second line, but having both won't hurt. The first line just protects against the Text component not having defaultProps which is the case for React Native 0.56.0 and above.

Add the above lines in the entry point file of your React Native application (usually index.js, app.js or main.js) to apply this prop to all Text components in your application.

This prop will only affect Text components and you may want to apply the same changes to TextInput which can be done with a similar snippet:

TextInput.defaultProps = TextInput.defaultProps || {};
TextInput.defaultProps.allowFontScaling = false;

Also note that some components wont obey font scaling settings, for example: Alert, PickerIOS, DatePickerIOS, TabBarIOS, SegmentedControlIOS as these are all natively drawn and don't rely on the Text component.

levi
  • 2,014
  • 2
  • 15
  • 15
  • 3
    Hackish, but brilliant nevertheless. Am using it. – Kaiwen Huang Sep 18 '18 at 10:35
  • @KiritModi I think Alert is rendered entirely natively -- so I'm guessing you're unable to control how text is rendered inside the modal. Instead you'd need to implement your own alert component. – levi Oct 23 '18 at 02:25
  • 11
    In case some of you are wondering where to implement this, place the above code right below your import statements in `~/index.js`. Be sure to also import the `Text` component into RN. BTW, I'm running RN 0.57.8. – Mix Master Mike Jan 16 '19 at 07:04
  • Text.defaultProps can sometimes be undefined, so it's better to use: `Text.defaultProps = Text.defaultProps || {}`. It handles both cases. – dphaener Jan 29 '19 at 19:00
  • @dphaener the original checked for `Text.defaultProps` being undefined. – levi Feb 04 '19 at 01:35
44

For React native 0.58+

Preferable to keep font scaling but you can limit it by using Text new prop maxFontSizeMultiplier

For React native 0.56+ use Levi's answer

Text.defaultProps = Text.defaultProps || {};
Text.defaultProps.allowFontScaling = false;

For React native 0.55 and lower

Add Text.defaultProps.allowFontScaling=false at the beginning of the app (e.g. main.js or app.js etc ...) to apply this prop on all Text components through out the whole app.

A-J-A
  • 2,344
  • 1
  • 17
  • 26
  • When i add it to constructor in App.js, i get error, do i miss something? – ROI Feb 23 '18 at 17:05
  • @AnshulKoka can you confirm this ? I was checking the documentation and didn't see anything concerning default props and allowFontScalling. – A-J-A Jul 12 '18 at 07:42
  • 2
    @A-J-A I just upgraded from react-native 0.55.4 to 0.56.0 today and Text.defaultProps comes out as undefined. – Anshuul Kai Jul 12 '18 at 08:46
13
When user increase full font size from setting 

Enlargement of size of the device font will not break (Styling wise).

index.js file


import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
import {Text, TextInput} from 'react-native';

AppRegistry.registerComponent(appName, () => App);

//ADD this 
if (Text.defaultProps == null) {
    Text.defaultProps = {};
    Text.defaultProps.allowFontScaling = false;
}

if (TextInput.defaultProps == null) {
    TextInput.defaultProps = {};
    TextInput.defaultProps.allowFontScaling = false;
}

<CalendarStrip
    shouldAllowFontScaling={false}
/>

Also note that some components wont obey font scaling settings, for example: Alert, PickerIOS, DatePickerIOS, TabBarIOS, SegmentedControlIOS as these are all natively drawn and don't rely on the Text component.

Keshav Gera
  • 10,807
  • 1
  • 75
  • 53
5

I'm kinda late, but if anyone wants a answer with Typescript, here it is

interface TextWithDefaultProps extends Text {
  defaultProps?: { allowFontScaling?: boolean };
}

(Text as unknown as TextWithDefaultProps).defaultProps = {
   ...((Text as unknown as TextWithDefaultProps).defaultProps || {}),
   allowFontScaling: false,
 };
Mike4610
  • 61
  • 2
  • 3
2
 if (Text.defaultProps == null) {
            Text.defaultProps = {};
            Text.defaultProps.allowFontScaling = false;
        }

I kept this piece of code inside the constructor of index.js.It really worked well. By the I am using react native version 0.59.9 FYI.

Trinadh Koya
  • 1,089
  • 15
  • 19
  • `Text.defaultProps = Text.defaultProps || {} ;` `Text.defaultProps.allowFontScaling = false;` This is equivalent to your code – A-J-A Jun 27 '19 at 23:11
1

Create an <AppText> component and use it with your presets instead of the original one, with your own default, including font scaling false. This is better because you can enrich it with your own API.

For example, my AppText permit to do things like:

<AppText id="some.translation.key" color="primary" size="l" underline italic bold/>

Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • Might be what you need in some circumstances, but what do you do if e.g. you want ReactNavigation to restrict the font scaling in `MaterialCommunityIcons` used in `headerRight`? Unfortunately using `` doesn't work. – Wodin Feb 16 '20 at 15:54
1

In another file, import the actual Text component as ScaledText so as a backup, and then redefine Text, overriding the allowFontScaling prop.

export function Text(props) {
  return <ScaledText {...props} allowFontScaling={false} />;
}

Then, import your locally defined Text component, instead of the built-in React Native Text. This is also useful if you want to elegantly disable font scaling on only certain parts of your app.

Joseph
  • 293
  • 4
  • 12
1

For webview we can use textZoom={100} props to handle font-size change if font size is changed from mobile setting.

if imported from react-native-webview

<WebView
    textZoom={100}
    source={}/>
Tushar Pandey
  • 4,557
  • 4
  • 33
  • 50
1

For IOS

index.js

import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
import {Text, TextInput} from 'react-native';

AppRegistry.registerComponent('appName', () => App);

if (Text.defaultProps == null) {
    Text.defaultProps = {};
    Text.defaultProps.allowFontScaling = false;
}

Note that some components like Alert, PickerIOS, DatePickerIOS, TabBarIOS, and SegmentedControlIOS won't obey font scaling settings as they are natively drawn and don't rely on the Text component.

For Android

import android.content.res.Configuration;
import android.util.DisplayMetrics;
import android.view.WindowManager;

public class MainApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    adjustFontScale(getResources().getConfiguration());
  }

  private void adjustFontScale(Configuration configuration) {
    configuration.fontScale = (float) 1.0;
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(metrics);
    metrics.scaledDensity = configuration.fontScale * metrics.density;
    getBaseContext().getResources().updateConfiguration(configuration, metrics);
  }
}

Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80