-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add styles based on the documentation tool #473
base: main
Are you sure you want to change the base?
Conversation
Use our heuristic to detect the documentation tool/theme and add specific `--readthedocs-*` CSS variables based on that for known tools/themes. Reference: readthedocs/readthedocs.org#11849 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe there is a better pattern here for dynamic styles. The Lit documentation probably suggests using classMap
on the element, which could be another option. We've talked about avoiding classes for styling though, so I mostly lean towards a dynamic styles
getter if it works easily.
Yes. Is there are way to detect if the
Would that make sense?
I'm not sure to understand what this means. Can you expand o this? |
I pushed a commit to what I understood it could be a better pattern for this. Let me know what you think. |
Using a getter for class SomeElement extends LitElemeent {
static get styles {
if (...) {
return css`...`;
}
return css`...`;
}
}
So, there is But it feels like better design to make this explicit and rely on existing CSS functionality for this. If we keep our rules low specificity, then user added rules can very easily be higher specificity -- and our styles are then overridden.
Using class names is a separate pattern, but also possible. In general, a pattern I like is to (re)use element properties for CSS rules instead of classes. Element properties have specific purpose and update the Lit element properties where class names don't do anything but affect CSS styles. That is: // The `tool` property affects the element reactive properties. This rule is specificity 0 1 1
readthedocsflyout[tool="docusaurus"] { ... }
// The CSS class is used only for styles, it doesn't affect the properties on the Lit element. Specificity 0 1 1
readthedocsflyout.tool-docusaurus { ... } We should keep specificity as low as possible either way. One wrench I'll give you though is that this is still just for So I think the styles you applied originally might be closer to what we want, we just shouldn't do this from inside a single element. This is something we should do a more global level. I might still suggest a class/attribute selector approach here though, which leverages CSS functionality instead of hiding this logic from user in JS. :root[data-readthedocs-tool="docusaurus"] { ... }
:root[data-readthedocs-tool="sphinx"] { ... } This gives a clear attribute users can remove and we can avoid applying an attribute if a user already specifies an attribute or something like |
I was trying to keep things scoped by addon. That is, from flyout we should be defining only settings that affect the flyout (e.g. Also, we can't do |
I pushed some changes that use We will need to do the same for the other addons, where we we want to increase/decrease the font sizes. However, I'm happy to start with flyout for now and grow from there if we find this is the pattern we will stick to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this approach with the CSS -- it feels really explicit which feels good.
@@ -31,9 +37,12 @@ export class FlyoutElement extends LitElement { | |||
super(); | |||
|
|||
this.config = null; | |||
this.classes = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we're setting this, and then overriding it on line 44?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.classes = {}; |
Seems this is still an issue?
If you need to manage these variables inside each addon then this is true, but what I was describing was applying these variables from the host DOM, at a global level. This is where users should/will be defining our CSS variables either way.
I do think isolation makes sense, but we can still do addon isolation of styles/variables at a global level. We don't need to apply Thinking more, we don't need an attribute or class on // Styles applied for docusaurus
html {
--readthedocs-flyout-font-size: 0.9rem;
--readthedocs-notification-font-size: 0.9rem;
} The easiest change for theme maintainers and users will be to add some CSS like: // `html body` or `html html` is higher specificity than our rules at `html`.
html body, html html {
--readthedocs-flyout-font-size: 2rem;
--readthedocs-notification-font-size: 2rem;
} This doesn't involve editing the doc tool theme HTML, so is the easiest control point. Defining these variables inside the shadow DOM like you're describing might take precedence over host applied variables though, we should test this. This would make it hard/impossible for this easy control of these variables. This all gives users/theme maintainers some way to control at least the styles applied by our magic, but it doesn't control or allow opt out from our magic detection. Attributes on each addon does accomplish this but it's rather cumbersome -- maintainers would have to define all our addons in HTML theme |
By using selectors like I think that using References:
Until then, this PR will give users a better UI/UX anyways since they won't have to do anything on their side. In other words, I'd like to give users the best default experience on their doctools/themes (at least the ones we known) for now (the proposal of this PR) and leave a more polished customization for the future. |
I don't fully understand the implementation details here, but the goal I assume is having good defaults, but letting users be able to override them. If we have to choose only 1, I think good defaults is more important, since the initial experience for the user is most important, and getting that right is going to make adoption much more likely. However, it really seems like we should be able to support both, where we can set a default, and the user can override it? |
Line height should almost always be derived from
What styles do we need that shouldn't be derived from font-size? This would be helpful to enumerate. The majority of styles seem like be positioning and spacing, both mostly proportional to Even if there are many other variables required, I still think adding more variables is a good pattern. These variables don't need to map directly to CSS styles directly even. CSS variables are a benefit because they avoid many of the downsides to JS and HTML customization. More control of CSS styles could render further customization needless even. But also important: a worst case failure of CSS customization is just improper display. JS and HTML customization can throw exceptions if we introduce changes that break user customization.
How do we replace user customization for this PR then, what are users expected to do to override our magic? So far I don't agree with removal, for the points above.
Agreed, I still think this is completely possible here too. Good defaults are helpful, but we really shouldn't be solely responsible for customization at every tool either. Retaining easy customization points shares this load and doesn't cut out theme maintainers. |
Yes, we should be able to support both. However, my proposal is to start with good defaults (this PR) and add support for With that, we can continue discussing how to support these CSS variables in a better way that works for all the cases, while we give a better UX to our users in the meanwhile. That said, I agree with the points that Anthony raised in the previous comment, but I'm trying to be more practical now while we debate and learn how to implement it in the near future. Footnotes
|
Next steps:
|
This PR is what I was describing above, for the most part: It reuses the documentation tool/theme attribute approach instead. But these rules are applied at the parent DOM and allow for users to control these values still. I would not set I didn't test this further with all of the different tools/themes, I'm not sure how you're testing these. But the underlying pattern for variable use is the most important part here. |
|
This moves the inner CSS rules from inside the shadow DOM to the parent DOM. This allows users to still set a `--readthedocs-font-size` and similar variables.
With this implementation, we can now use a CSS more specific selector to re-define these variables. I understand this is exactly what @agjohnson was suggested and wanted me to use now 😄 Example with a small GIF:
|
We don't need to tell the users to perform extra steps on these documentation tools because addons is going to do this by default now: readthedocs/addons#473
We don't need to tell the users to perform extra steps on these documentation tools because addons is going to do this by default now: readthedocs/addons#473 <!-- readthedocs-preview docs start --> --- :books: Documentation previews :books: - User's documentation (`docs`): https://docs--11897.org.readthedocs.build/en/11897/ <!-- readthedocs-preview docs end --> <!-- readthedocs-preview dev start --> - Developer's documentation (`dev`): https://dev--11897.org.readthedocs.build/en/11897/ <!-- readthedocs-preview dev end -->
I thought we wanted folks to be able to define the |
/* These variables are used more than once, use a local variable so we can set | ||
* a default in this addon */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very useful docstring 💯
@@ -31,9 +37,12 @@ export class FlyoutElement extends LitElement { | |||
super(); | |||
|
|||
this.config = null; | |||
this.classes = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.classes = {}; |
Seems this is still an issue?
Because we add rules as
|
Because we add rules as
This seems like a great thing to add to the docs 💯 |
Added here: readthedocs/readthedocs.org@a371da0 |
Actually, it's not needed to target Edit: it could be, I put some notes in #488 |
Updated again at #487 |
Use our heuristic to detect the documentation tool/theme and add specific
--readthedocs-*
CSS variables based on that for known tools/themes.Reference: readthedocs/readthedocs.org#11849 (comment)