Giter Club home page Giter Club logo

Comments (9)

JayPanoz avatar JayPanoz commented on September 15, 2024

So to sum things up:

  • all values are strings (even integers e.g. page margins);
  • all user settings have a property and a value e.g. --RS__userSettingProperty: userSettingValue; so that’s name + value in the model;
  • this pair is separated by a colon (:), pairs are separated by a semicolon (;);
  • user settings should be appended in a style attribute on html – if the attribute is already present, user settings should be added to it, not override the existing value;
  • some settings need what we call flags i.e. advanced settings like word-spacing, cf. “required flag” in the ReadiumCSS docs.

And that’s pretty much it. Adding settings to the html element is basically our best option there as rendering engines are optimized for that use case – it’s an easy performance trick.

A question though: currently all user settings are persistent across ebooks. Do we want to keep it that way or reserve persistence to some settings – in which case, we could have a mapping to the user overrides classification.

from swift-toolkit.

HadrienGardeur avatar HadrienGardeur commented on September 15, 2024

some settings need what we call flags i.e. advanced settings like word-spacing, cf. “required flag” in the ReadiumCSS docs.

From a model perspective, these will separate values. At an "app" level (the test app in our case), we could certainly be a little smarter though and tie several values together.

from swift-toolkit.

JayPanoz avatar JayPanoz commented on September 15, 2024

Yeah definitely. Perhaps the most important is that the flag for advanced settings is shared so if one advanced user setting is already using it, you’re good to go for others requiring it.

[edit] Clarify which flag is shared.

from swift-toolkit.

clementbmn avatar clementbmn commented on September 15, 2024

If UserProperties.css= "color: blue;"
Arent <link rel="stylesheet" type="text/css" href="UserProperties.css"/>
and <html style="color: blue;"/> basically the same thing ?
Simple question

from swift-toolkit.

JayPanoz avatar JayPanoz commented on September 15, 2024

Hmm,

<link rel="stylesheet" type="text/css" href="UserProperties.css"/>

and

<style type="text/css">
  /* same content as stylesheet */
</style>

are indeed more or less the same thing but we’re not doing that in ReadiumCSS, although that’s an option should an implementer use another CSS library.

Currently, what we’re doing is something like:

<html style="--USER__fontOverride: readium-font-on; --USER__fontFamily: 'Helvetica'; --USER__advancedSettings: readium-advanced-on; --USER__fontSize: 200%;">

So that’s

<html style="name: value; name: value; name: value; name: value">

in the new user settings model. ReadiumCSS is indeed using the style names and/or values to apply the styles so if they’re not present in <html>, user settings won’t work.

The alternative being injecting the entire styles for each setting via <link> or <style> but right now we get a performance boost with inline styles on <html>.

from swift-toolkit.

JayPanoz avatar JayPanoz commented on September 15, 2024

Took some extra look at the model on the r2 repo and just recording my thoughts but…

If developers want to use <link> or <style> i.e. injecting in <head>, an additional and optional property like link or something would probably help. You need name and value anyway but we currently have nothing to deal with separate stylesheets.

from swift-toolkit.

HadrienGardeur avatar HadrienGardeur commented on September 15, 2024

I think the way we inject <link> for both CSS and JS also needs its own abstract model, similar to what we're discussing for user settings. Right now, this lacks the flexibility and modularity that we're looking for.

from swift-toolkit.

JayPanoz avatar JayPanoz commented on September 15, 2024

Yeah will open an issue in ReadiumCSS as well, as the “build” process currently covers only one case i.e. setting inline styles on <html> and there is no way you can compile each user setting, it’s all or nothing.

from swift-toolkit.

JayPanoz avatar JayPanoz commented on September 15, 2024

Post Engineering Call Recap

We have 3 different options there:

  1. injecting stylesheets using <link>;
  2. injecting styles using <style>;
  3. injecting inline styles i.e. <html style="">.

We’re currently using option 3. It’s worth noting option 1 and 2 still require custom properties to be set. Here’s the pros and cons for each option.

Injecting stylesheets using <link>

It’s basically about using a static representation* of ReadiumCSS user settings submodules dynamically. You append a <link> when the user sets a preference and remove it when the user resets this pref.

* Those have to be “compiled” using an altered version of our PostCSS config first.

For the pref to work, you still need to use CSS custom properties for settings which value can be incremented/decrement and/or CSS classes for static values e.g. reading modes.

Examples

<html style="name; value">
  <head>
     …
    <link href="stylesheet" id="ref" type="text/css" rel="stylesheet" />
  <head>
  <body>
    …
  </body>
</html>

or

<html>
  <head>
     …
    <link href="stylesheet" id="ref" type="text/css" rel="stylesheet" />
    <style type="text/css" id="ref-prop">
      :root { name: value; }
    </style>
  <head>
  <body>
    …
  </body>
</html>

Pros:

  • That should guarantee a reflow in rendering engines (although CSS multicol may well call that into question in some circumstances)
  • No need for flags/complex selectors/etc. to handle user prefs
  • in theory, would work a little bit better with HTTP2 – this is not necessarily the case in practice right now

Cons:

  • You must keep track of injected stylesheets in order to remove them later
  • You now have to handle both a <link> and a custom property
  • Since selectors are simpler in the stylesheet, their specificity is lower, which means more authors’ stylesheets may well override user settings
  • Must work in combination with 2 or 3 to set the custom property (unless there is another way)

injecting styles using <style>

It’s basically about writing styles directly in the DOM instead of linking to a css file. You append a <script> with the needed styles when the user sets a preference and remove it when the user resets this pref.

For the pref to work, you still need to use CSS custom properties for settings which value can be incremented/decrement and/or CSS classes for static values e.g. reading modes.

Examples

<html>
  <head>
     …
    <style type="text/css" id="ref">
      :root { name: value }
      html {
        font-size: var(name) !important;
      }
    </style>
  <head>
  <body>
    …
  </body>
</html>

Note that’s the simplest example, most user settings have much larger styles to write.

Pros:

  • That should guarantee a reflow in rendering engines (although CSS multicol may well call that into question in some circumstances)
  • No need for flags/complex selectors/etc. to handle user prefs
  • In theory, you can inject that anywhere, even at the very end of <body>
  • You can work without custom properties as you could very well use template stylesheets with placeholders for the value

Cons:

  • You must keep track of <style> elements in order to remove them later
  • Strong binding i.e. you must write the styles instead of linking to them (how do you implement CSS updates? etc.)
  • Since selectors are simpler in the stylesheet, their specificity is lower, which means more authors’ stylesheets may well override user settings
  • When you need to change the value of the custom prop, it’s unclear whether modifying the value in the existing <style> is a better option than removing it and re-appending it.

injecting inline styles i.e. <html style="">

It’s basically about adding, updating and removing custom properties in the style attribute of the <html> element. The ReadiumCSS-after.css stylesheet takes care of everything else. It’s worth noting we could do with static representations of the ReadiumCSS user submodules instead of bundling them.

Examples

<html style="name; value">
  <head>
     …
  <head>
  <body>
    …
  </body>
</html>

Pros:

  • Logic is scoped to the <html> element, everything else is taken care of in CSS
  • Even though it’s a side-effect, it forces us to have selectors with a higher specificity, which helps reduce the risk of authors’ stylesheets overriding/breaking user settings
  • Rendering engines may use performance tricks to make that super fast

Cons:

  • We need to use CSS tricks to force reflow/relayout – it’s unclear we wouldn’t need some with the 2 previous options though
  • Those are hooks authors can use i.e. they can use the name or value in selectors to target ReadiumCSS
  • We need flags (some settings are requiring 2 custom props)

Please feel free if I missed anything or if it’s unclear. Lists of pros and cons are by no means exhaustive so please feel free to add items to them.

from swift-toolkit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.