Comments (9)
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’sname
+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 onhtml
– 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.
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.
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.
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.
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.
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.
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.
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.
Post Engineering Call Recap
We have 3 different options there:
- injecting stylesheets using
<link>
; - injecting styles using
<style>
; - 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)
- Errors while loading a Resource in GCDHTTPServer are not bubbled up HOT 5
- 'asSQL' is inaccessible due to 'internal' protection level HOT 2
- Name collision caused by GCDWebServer dependency HOT 5
- Error"Error initializing db." HOT 13
- Nondeterministic loading issue with `EPUBNavigatorViewController` HOT 2
- [Feature] Add support for new LCP Profiles
- Logic behind the selected text information for remote server HOT 2
- Pagination after increasing the font size HOT 4
- [Bug] EditingActions like Define Lookup are not shown. HOT 1
- [develop] Locator href for exploded archive audiobook incorrectly starts with leading slash HOT 2
- [develop] Opening exploded archive audiobook inside App Group fails with `Publication.OpeningError.unsupportedFormat` in (Designed for iPad) Mac app HOT 9
- [Bug] Search Result Chapter Title HOT 6
- lcpl file which is pub format can't be open by publication.metadata.identifier is nil HOT 6
- `Navigator.go` results in misaligned view HOT 9
- [Bug] iOS Reader Search crashed with 4-5 character HOT 1
- [Bug] Expression is 'async' but is not marked with 'await' HOT 1
- iOS Text to Speech feature crashing HOT 2
- [Documentation] Locator -> Location -> progression and totalProgression properties calculation
- PDF in landscape mode HOT 1
- [Bug] iOS 17: Unable to add any `EditingAction`s to the selection menu HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swift-toolkit.