Skip to content
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

Page is unstyled by default due to dark option #959

Closed
QuLogic opened this issue Sep 29, 2022 · 7 comments · Fixed by #1045
Closed

Page is unstyled by default due to dark option #959

QuLogic opened this issue Sep 29, 2022 · 7 comments · Fixed by #1045

Comments

@QuLogic
Copy link
Contributor

QuLogic commented Sep 29, 2022

The instructions for dark/light theming specify:

/* anything related to the light theme */
html[data-theme="light"] {
}
/* anything related to the dark theme */
html[data-theme="dark"] {
}

and I believe this is used in the theme itself. But this means there is no theming applied until the JavaScript runs and sets data-theme on the html. If you block pydata-sphinx-theme.js (which of course breaks many things), then no theming will be applied.

The delay in the JavaScript can cause it to appear as if the theme is lagging, matplotlib/mpl-brochure-site#67 (comment) (ignore the first half of the video which is our bug.)

There are probably multiple ways to fix this. One way to fix it is to (if defaulting to light theme), do html, html[data-theme="light"] for the CSS selector. Since html[data-theme="dark"] is more specific, it will override the html one. The other way is to edit the HTML to set a default on the the element, <html lang="en" data-theme="light">. Both options will at least give some styling to the page until the JavaScript sets the correct theme. That doesn't work if you revisit a page after setting dark mode though, but this is already flashing anyway.

@QuLogic
Copy link
Contributor Author

QuLogic commented Sep 29, 2022

AFAICT so far, none of the premade (but client-side only) solutions are able to avoid the light-to-dark flash when returning to a site, if the site defaults to light and the user switched to dark, or vice versa.

I'm not sure, but perhaps one can use media queries to at least fix it for the system setting:

/* anything related to the light theme */
@media(prefers-color-scheme: light) {
  html {
    /* light style */
  }
}
html[data-theme="light"] {
  /* light style */
}
/* anything related to the dark theme */
@media(prefers-color-scheme: dark) {
  html {
    /* dark style */
  }
}
html[data-theme="dark"] {
  /* dark style */
}

But this requires writing out the styles twice, and I haven't confirmed that this actually works any better.

@drammock
Copy link
Collaborator

@12rambau are you OK with the general approach of having "light" be the default styling? If so either of these options seem reasonable to me:

One way to fix it is to (if defaulting to light theme), do html, html[data-theme="light"] for the CSS selector. Since html[data-theme="dark"] is more specific, it will override the html one. The other way is to edit the HTML to set a default on the the element, <html lang="en" data-theme="light">.

I'll let you pick which seems better.

@12rambau
Copy link
Collaborator

I first want to clearly understand what is happening and reproduce it from my side. The very reason why this is set here (

) before the body is to prevent any display before the theme is set. To my understanding, if the js fails then the whole page should fail.

I think forcing the light theme by default will just make it flicker for anyone setting up the dark theme.
In short I need to create a small reproductible example

@QuLogic
Copy link
Contributor Author

QuLogic commented Sep 30, 2022

I first want to clearly understand what is happening and reproduce it from my side. The very reason why this is set here before the body is to prevent any display before the theme is set.

I don't think that prevents displaying anything. It just attempts to set the theme mode very early. I don't know why that doesn't work for us.

I think forcing the light theme by default will just make it flicker for anyone setting up the dark theme. In short I need to create a small reproductible example

OK, I went through all the sites in the gallery, and the results are interesting. Of those sites, few of them are on the latest theme with dark mode enabled, and even fewer have any custom header colours. SciPy sets a custom colour with a general h1{colour:...} and no dark override, so it automatically works on light mode. Arviz sets --pydata-color-primary in a custom.css that is linked at the end of the CSS just before the pydata-sphinx-theme.js preload. However, Arviz does not seem to show this flash from unstyled to styled.

In Matplotlib, we set --pydata-color-primary in a CSS file that is not last, but it is after pydata-sphinx-theme.css, so it should be similar to Arviz, yet we see the unstyled content first.

Looking at the dev console, I see this message:

Layout was forced before the page was fully loaded. If stylesheets are not yet loaded this may cause a flash of unstyled content.

but I have no idea what is causing that.

As a test, I commented out all scripts in head and the late script load before the footer, and left just the script that you linked above. I opened the inspector and reloaded, but still see the unstyled content and about 2 seconds later, the script finally updates the data variables and the styles get applied. (Note, the delay is shorter without the inspector open, just enough to notice though.) So it's apparently not caused by our scripts, but I don't know what it could be.

If you have any ideas of where to look, I can try out something. Also, this is with Firefox 104.0.2 if that matters.

@QuLogic
Copy link
Contributor Author

QuLogic commented Oct 29, 2022

Good news, I think I have figured out the problem. The problem is not the theme; the problem is CloudFlare! Its rocket loader defers all scripts, including the one you pointed out above, causing no defaults to get applied initially.

What do you think of adding their disabler to that script? It's just adding data-cfasync="false" in the tag.

@drammock
Copy link
Collaborator

What do you think of adding their disabler to that script? It's just adding data-cfasync="false" in the tag.

+1 and thanks for figuring it out!

@12rambau
Copy link
Collaborator

12rambau commented Oct 29, 2022

The problem is not the theme

🍾 I was failing to reproduce it locally and was very surprised by the behavior you were describing

its rocket loader defers all scripts

very nice catch indeed

What do you think of adding their disabler to that script? It's just adding data-cfasync="false" in the tag.

that's armless for everything else so I'm +1 for this one. happy to review a PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants