Skip to content

fontWeight preference has no effect on single-face fonts #239

Open

Description

@atani

Summary

EPUBPreferences.fontWeight has no visible effect on fonts that ship only a single (Regular) face, such as user-imported fonts declared via fontFamilyDeclarations. WebKit does not appear to synthesize bolding in this situation, so the preference silently does nothing for those fonts.

Environment

  • swift-toolkit at develop 8811f0e (also reproduces on 3.10.0 with data-URI-embedded fonts)
  • iOS 26.5 simulator (iPhone 17), WKWebView
  • Font declared with CSSFontFamilyDeclaration / CSSFontFace (single face, no weight descriptor, i.e. default 400)

Reproduction

  1. Register a single-face font with Configuration.fontFamilyDeclarations and select it via EPUBPreferences.fontFamily.
  2. Set EPUBPreferences.fontWeight = 1.5 (mapped to font-weight: 600 by ReadiumCSS.userProperties).
  3. Compare renders at fontWeight = 1.0 and 1.5.

Result: the two renders are pixel-identical (we diffed screenshots). With a multi-face system font (Georgia) the preference works, but only by snapping to the real Bold face.

Expected

Either gradual (or at least synthetic) bolding for single-face fonts, or documentation that fontWeight requires a multi-face or variable font.

Notes

  • We did not find font-synthesis overridden in Readium CSS, so this looks like WebKit's own reluctance to synthesize bold for downloaded fonts at weight 600. We only tested 600; higher values may behave differently.
  • As a workaround in our reader we layer -webkit-text-stroke (em-scaled from the weight preference, currentColor) on top of the native font-weight, which gives gradual thickening for any font. If there is interest, this could be an opt-in behavior of the fontWeight preference in Readium CSS.

Happy to contribute a patch if the maintainers have a preferred direction.

Activity

  1. mickael-menu commented on Jul 12, 2026

    @mickael-menu
    Member

    Thank you for opening this feature request! I wasn't aware this was possible. @JayPanoz, would we be interested in adding this to Readium CSS? You can find the suggested implementation here: readium/swift-toolkit#854

    Regarding the PR, I think it might be better to contribute this directly to Readium CSS rather than implementing it in each toolkit.

  2. atani commented on Jul 13, 2026

    @atani
    Author

    Makes sense — a Readium CSS implementation would benefit every toolkit at once. I'm happy to draft a PR against readium-css once @JayPanoz weighs in on the preferred shape (a user-settings flag next to the existing font-weight handling, presumably). I'll keep readium/swift-toolkit#854 open as a reference implementation in the meantime, and close it once the CSS-level version lands.

  3. JayPanoz commented on Jul 13, 2026

    @JayPanoz
    Collaborator

    Makes sense, if Swift has this bug, chances are we are impacted in Safari (Web/TS-Toolkit) as well.

    So assuming font-synthesis does not bring the expected result I guess I will have to open an issue in Webkit’s tracker, if it was not reported already. I have other issues to log so I can handle it.

    That should also help check whether the same bug applies to MacOS – surprisingly we are finding a lot of iOS/iPadOS-specific bugs lately so I will not assume it applies to MacOS without checking first 😓 If the result differs across platforms I’ll also have to check desktop-class in iPadOS just because Webkit.

    Then the question is:

    • should it be a patch i.e. the value is hardcoded.
      This would be preferred as it would instantly tell this is not for consumption on Chromium- and Gecko-based rendering engines, and we already have iOSPatch and iPadOSPatch available in ReadiumCSS.
      Best case scenario, the issue does not apply on MacOS and we could piggyback on these two
    • should it be a full-fledged property i.e. the value can be modified dynamically by the consuming app, because say a hardcoded value does not fit all fonts.
      This would be trickier as we would need to signal it is webkit-only so presumably prefixing the property with webkit

    Given the implementation I just took a look at, a patch might be challenging. ReadiumCSS basically takes the value you give it, which can be 400, 700 but also bold, bolder, etc. so computing the stroke width cannot be guaranteed. I think we’ll need to carefully pick the name of the property so that the intent is super clear.

  4. changed the title [-]fontWeight preference has no effect on single-face fonts declared with fontFamilyDeclarations[/-] [+]fontWeight preference has no effect on single-face fonts[/+] on Jul 15, 2026
  5. JayPanoz commented on Jul 28, 2026

    @JayPanoz
    Collaborator

    Right so ATM I cannot reproduce the issue with a simple test case using multiple fonts in different formats.

    Font-synthesis is doing what it expected from it e.g. 400 is applied for 100→500, (faux) bold is synthesised for 600→900

    E.g.

    Image Image Image

    Could you point me to the exact font displaying this issue? I need to check its metadata to see if there is not something preventing Webkit from synthesising in the first place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions