Skip to content

font-family fallback not honored when first font in family not available (Android & iOS) #2974

Description

@Brett208

Description

On Android and iOS, if the first font in a font-family is not available, text will be rendered using the system default font, not the next font in the font-family.

Version Information:

  • Expo SDK version 54.0.0
  • Android version tested: Version 16, on an emulated Pixel 9 Pro
  • iOS version tested: iPhone 16 Pro
{
  "dependencies": {
    "react-native-paper": "4.9.2",
    "@expo/vector-icons": "^15.0.3",
    "react-native-svg": "15.12.1",
  }
}

This bug was noted on an actual Android phone in addition to the snack emulator (https://snack.expo.dev). The script to reproduce is in the procedures to reproduce section.

Notice in the screenshots below for Android and iOS the font-family fallback is not being honored. The third svg renders using the system default (no serifs) even though the fallback font should have serifs and we verified this font worked in the second render.

On Android:
Image

On iOS:
Image

Notice, I had trouble using the generic font serif on iOS, but that appears to be a separate issue then the font-family. The generic font serif worked correctly on Android.

Using the generic serif keyword for a font does not appear to resolve correctly in react-native-svg on iOS, which is a related but separate issue.

Relevant SVG specification section excerpt:

From the SVG 1.1 specification (https://www.w3.org/TR/SVG11/text.html)

10.10 Font selection properties
SVG uses the following font specification properties. Except for any additional information provided in this specification, the normative definition of these properties is in CSS2 ([CSS2], chapter section 15.2). Any SVG-specific notes about these properties are contained in the descriptions below.

Relevant CSS specification section excerpt:

From the CSS Fonts Module Level 3 (https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/)

body {
font-family: Helvetica, Verdana, sans-serif;
}
If Helvetica is available it will be used when rendering. If neither Helvetica nor Verdana is present, then the user-agent-defined sans serif font will be used.

Steps to reproduce

Place the following script into snack using an Android or iOS emulator:

import { View } from 'react-native'
import { Svg, Text } from 'react-native-svg'

export default function App() {
  return (
    <View style={{ paddingTop: 60, paddingHorizontal: 60, gap: 16 }}>

      {/* Demonstrate the system default font (San Francisco on iOS, Roboto on Android) */}
      <Svg height="60"><Text y="40" fontSize={40}>The quick brown fox jumped</Text></Svg>

      {/* Demonstrate a serif font is available for rendering svg text on the platform (use serif on Android and Georgia on iOS.)*/}
      <Svg height="60">
        <Text y="40" fontFamily="serif" fontSize={40}>The quick brown fox jumped</Text>
      </Svg>

      {/* Demonstrate svg incorrectly falls back to OS system default, not the next font in the font family (use serif for second font on Android and Georgia for second font on iOS). */}
      <Svg height="60">
        <Text y="40" fontFamily="MissingFont, serif" fontSize={40}>The quick brown fox jumped</Text>
      </Svg>

    </View>
  )
}

Snack or a link to a repository

https://snack.expo.dev/@brett208/react-native-svg-font-family-bug?platform=ios

SVG version

15.12.1

React Native version

4.9.2

Platforms

Android

JavaScript runtime

None

Workflow

None

Architecture

Paper (Old Architecture)

Build type

None

Device

Real device

Device model

Motorola g power 5G (XT2415V)

Acknowledgements

Yes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions