Skip to content

Should we expose line height compensation var? #229

Open

Description

@JayPanoz

See search for context: https://github.com/search?q=repo%3Areadium/css%20--RS__lineHeightCompensation&type=code

In the base module, we are setting a line height compensation for our default line-height:

/* For square-ish fonts (CJK, Indic, etc.), we must apply some compensation in dynamic leading. Default is 1 i.e. no compensation */
--RS__lineHeightCompensation: 1;
--RS__baseLineHeight: calc(1.5 * var(--RS__lineHeightCompensation));

The comment says it all

/* For square-ish fonts (CJK, Indic, etc.), we must apply some compensation in (dynamic) leading. Default is 1 i.e. no compensation */

Although it needs to be updated to no longer refer to dynamic leading.

And this is what we do here for instance:

:lang(am) {
--RS__baseFontFamily: Kefa, Nyala, Roboto, Noto, "Noto Sans Ethiopic", serif;
--RS__lineHeightCompensation: 1.167;
}

Host apps of Readium CSS do not have access to these values, unless they keep a Map of lang – value, and we could expose them as vars, as we do for default colors or font family stacks for instance.

This would probably be helpful for a line-height user setting if you have values defined for Latin, and they do not play nicely in some languages e.g. if your max line-height is 1.75 chances are that is the publisher’s value in CJK cos it is usually 15–20% more with ideographs, so the user is only able to reduce line-height with your setting.

/* For CJK, the line-height is usually 15–20% more than for Latin */
--RS__lineHeightCompensation: 1.167;

In that case you would be able to check the compensation factor Readium CSS sets as a reference, and adjust your values accordingly if needed.

We already have this issue in Thorium Web, as our 3 settings presets are generally for Latin. So we will need to adjust anyway in an upcoming release to improve i18n, and we generally import these JSON from Readium CSS to retrieve the ref.

Another option is applying this compensation in the line-height user setting submodule: https://github.com/readium/css/blob/2982c7da924df2c4e27bf219cb80cda79836aea8/css/src/modules/user-settings-submodules/ReadiumCSS-lineHeight_pref.css

But it breaks the assumption that Readium CSS should not be opinionated and must not surprise implementers. If they do not see their given value applied, I’d argue this is surprising, especially for developers who are not dealing with Latin languages by default.

CC @danielweck @mickael-menu

Activity

  1. mickael-menu commented on Apr 29, 2026

    @mickael-menu
    Member

    If I understood this correctly, the idea is in the RS to multiply the user-selected line height (which might be a preset provided by the app) by the --RS__lineHeightCompensation of Readium CSS for the publication's language?

    I think this would be useful. I would have no use for CSS variables though, but would be interested in either (or both):

    • A Markdown documentation with a table of the mappings.
    • A JSON document that could be parsed by the toolkit to get the mappings dynamically.
  2. JayPanoz commented on Apr 30, 2026

    @JayPanoz
    CollaboratorAuthor

    f I understood this correctly, the idea is in the RS to multiply the user-selected line height (which might be a preset provided by the app) by the --RS__lineHeightCompensation of Readium CSS for the publication's language?

    That is correct. Then the app uses these as it sees fit e.g. your preset and stored value stays consistent, it just is compensated depending on the language of the publication when you submit the preference, and normalised when you get the setting.

    A JSON document that could be parsed by the toolkit to get the mappings dynamically.

    I can see the postcss plugging we are using can handle objects here: https://github.com/AgentCosmic/postcss-import-json#example

    I would be tempted to kill two birds with one stone and have something like:

    { 
      latin: {
        lineHeightCompensation: 1,
        baseFontFamily: var(--RS__oldStyleTf)
      },
      am: {
        lineHeightCompensation: 1.167,
        baseFontFamily: Kefa, Nyala, Roboto, Noto, "Noto Sans Ethiopic", serif
      }
    }
    

    Then ReadiumCSS just handles it internally as variables and they are created on build, but JSON can be used for data. We already do in Thorium Web BTW, See https://github.com/edrlab/thorium-web/blob/4e0da31479116d649d858b6e02d3997d6526bf59/src/preferences/models/theme.ts#L1-L27 for instance.

    I will also rename the existing JSON properties to drop prefix RS__ as I can use prefix in config.

    A Markdown documentation with a table of the mappings.

    Could be just a node script that could be run on build, and creates tables for each input file. It is so trivial since it is all about patterns that probably an agent could create it without too much fuss if we are being honest.

    Does that look good to you?

  3. mickael-menu commented on Apr 30, 2026

    @mickael-menu
    Member

    That looks like a great solution!

    What would be the keys in the JSON? That would be easier from a RS side to use BCP-47 language codes, but I guess you need something else on the CSS side. How would we map from a BCP-47 language code to the keys?

  4. JayPanoz commented on Apr 30, 2026

    @JayPanoz
    CollaboratorAuthor

    Guess it would be easier to discuss this through a PR: #230

    So would look possibly something like this: https://github.com/readium/css/pull/230/changes#diff-a09e600c502236e19c381d52f4ef1118260afc512dbde22c825b08a5782cbb54

    With the MD here: https://github.com/readium/css/blob/da160d8d4ef971f2648985132699511f489877c2/css/vars/CSS-Variables.md

    Internally these are just variables used in place of hardcoded values. https://github.com/readium/css/pull/230/changes#diff-2aec4119f823de33251dfdd357f833e328c92217dce3176e16dd965b6eeec376

    So it is pretty transparent as far as the CSS side is concerned.

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