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

Flashing when switching between pages in dark theme. #1325

Open
wenyaoliu opened this issue May 26, 2022 · 10 comments · May be fixed by #12173
Open

Flashing when switching between pages in dark theme. #1325

wenyaoliu opened this issue May 26, 2022 · 10 comments · May be fixed by #12173
Assignees
Labels
early-in-release An issue that should be worked on early in the release (likely due to risk) enhancement New feature or request themes Related to HTML theming or any other style related issue (like highlight-style) websites Issues creating websites
Milestone

Comments

@wenyaoliu
Copy link

When you define two themes, one light and one dark. It shows a button for switching light and dark, which is very good.

However, if you choose the dark mode and switch between different pages, chapters or sections. The website is flashing to the light mode first and change to dark theme. It is obvious and easily noticed.

I don't know the reason, but Hugo website do not have this issue. Quarto is great and I really like it, hope it better. Thanks.

@dragonstyle
Copy link
Collaborator

This is a great suggestion and something that I've already put some time into trying to improving. Since the dark/light styling is generated entirely using CSS, it is challenging to avoid this! I will investigate the Hugo solution and do my best to get this fixed sometime soon.

@dragonstyle dragonstyle transferred this issue from quarto-dev/quarto-web Jul 7, 2022
@jjallaire jjallaire added this to the Future milestone Jul 8, 2022
@dloss
Copy link

dloss commented Sep 26, 2022

I have noticed the same issue with Quarto 1.1.251 and Chrome 105. No flashing though with Firefox 104.

It seems the page is nearly fully rendered first with the light theme and only then switched to the dark theme by the quarto-html-after-body script at the end of the <body> element. Google tells me this is so common that it has a name: FOUC

Two solutions suggested on SO:

@dragonstyle
Copy link
Collaborator

Thanks for the suggestions - I will tinker a bit more and see if either remove or reduce the FOUC..

@dragonstyle dragonstyle modified the milestones: Future, v1.2, v1.3 Sep 26, 2022
@dragonstyle
Copy link
Collaborator

Because we implement our themes based upon toggling linked stylesheets (e.g. toggling the alternate/dark on or off on top of the existing light style), there is at least some latency introduced by the stylesheet fetch. I tinkered a bit with trying to be very optimal in how we process these stylesheets, including trying to reorder the link tags very early in the load process, but in each case the flash remained (and in many cases was unfortunately worse).

I think the solution maybe to consolidate the generated theme CSS into a single stylesheet with appropriate dark/light selectors at the root level. This is larger task and so I'm leaving this open for 1.3 to track.

@dloss
Copy link

dloss commented Feb 2, 2023

Any news on this?

@dragonstyle
Copy link
Collaborator

No update yet- this is something that I'd like to get to but am still working through other priorities.

@dragonstyle dragonstyle modified the milestones: v1.3, v1.4 Feb 20, 2023
@dragonstyle dragonstyle added the early-in-release An issue that should be worked on early in the release (likely due to risk) label Mar 13, 2023
@th0ger
Copy link

th0ger commented Oct 4, 2023

Yeah, users don't like this flashing.

If the new Bootswatch paired light/dark mode is implemented correctly #6741, can this improve the situation? The https://getbootstrap.com/ page itself has no flashing.

@dragonstyle dragonstyle modified the milestones: v1.4, v1.5 Nov 28, 2023
@dragonstyle dragonstyle added websites Issues creating websites themes Related to HTML theming or any other style related issue (like highlight-style) labels Feb 7, 2024
@dragonstyle dragonstyle modified the milestones: v1.5, v1.6 Feb 23, 2024
@mcanouil mcanouil added the enhancement New feature or request label Apr 28, 2024
@cscheid cscheid modified the milestones: v1.6, v1.7 Nov 18, 2024
@gordonwoodhull gordonwoodhull self-assigned this Feb 25, 2025
@gordonwoodhull
Copy link
Contributor

gordonwoodhull commented Feb 25, 2025

I tried all the same kinds of things that @dragonstyle mentions, just mucking about in the html output. Nothing helped.

Then I saw that the dark stylesheet is rel="prefetch", which means it will load in the background.

Actually tbh I had given up and said "I do not know what prefetch is, why not try stylesheet". And it got rid of the flash.

Then I read about prefetching, and I think we don't want the dark stylesheets to load in the background, because we may need them immediately.

Have not found where this HTML is generated yet.

@mcanouil
Copy link
Collaborator

mcanouil commented Feb 25, 2025

This?

  • const disableStylesheet = (stylesheets) => {
    for (let i=0; i < stylesheets.length; i++) {
    const stylesheet = stylesheets[i];
    stylesheet.rel = 'prefetch';
    }
    }
    const enableStylesheet = (stylesheets) => {
    for (let i=0; i < stylesheets.length; i++) {
    const stylesheet = stylesheets[i];
    stylesheet.rel = 'stylesheet';
    }
    }

And

@gordonwoodhull
Copy link
Contributor

gordonwoodhull commented Feb 25, 2025

Thanks @mcanouil! Yes it seems to be the latter.

We will still need to set body.quarto-dark or body.quarto-light much earlier to avoid a flash of white plots, but removing those three lines makes the page itself load without flashing.

It looks like it was added in 92e0b15 in an attempt to eliminate the FOUC, and we enable or disable the stylesheets using rel=stylesheet or rel=prefetch.

I think what is going on is that rel=prefetch both disables and pre-fetches the stylesheet. We don't want it to load in the background, but we do want to disable it dynamically. So e.g. changing disableStylesheet() to

       stylesheet.rel = 'disable-stylesheet'; 

almost works, but now we have a (perceptually much quicker) flash of black in light mode from removing the prefetch on the initial tag.

Which then can be eliminated by moving the script to the top of the body instead of the bottom. This also fixes the flash of white plots in dark mode, and is the recommendation of this well-regarded answer on SO.

I didn't see any issues, but if there are reasons that parts of the JS need to run after the content is loaded, or if this is a performance concern, we can split the JS into two scripts quarto-html-before-body and quarto-html-after-body.

gordonwoodhull added a commit that referenced this issue Feb 25, 2025
fixes #1325

introduces a new script before the body
which runs immediately, enabling/disabling stylesheets
and setting body.quarto-light or body.quarto-dark
gordonwoodhull added a commit that referenced this issue Feb 26, 2025
fixes #1325

introduces a new script before the body
which runs immediately, enabling or disabling dark mode

TODO: needs to degrade properly when JS is disabled
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
early-in-release An issue that should be worked on early in the release (likely due to risk) enhancement New feature or request themes Related to HTML theming or any other style related issue (like highlight-style) websites Issues creating websites
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants