Avoiding Flash with Multiple Stylesheets and JavaScript Style Switchers using Cookies and PHP

The problem with using multiple style sheets for different themes is that when the active stylesheet isn’t the first one in the HTML, the page may “flash” momentarily when reloaded or clicking through pages.

This seems to become more prevalent when onlick events have to be converted to scripts using event listeners to make a page compliant with CSP, especially if nonces or hashes are used.

A simple solution to this is to set a cookie using a different name than the one the style switcher uses, and then retrieve the cookie to rearrange the stylesheets so the active one is first in the list. For example, the JS for the listener can be modified thusly:

document.getElementById("lightTheme").addEventListener("click", function() {
    setActiveStyleSheet('light'); document.cookie = "theme=light"; return false;
});
document.getElementById("darkTheme").addEventListener("click", function() {
    setActiveStyleSheet('dark'); document.cookie = "theme=dark"; return false;
});

The style switcher sets a cookie named style, so I use theme to avoid conflicts. (I tried using style, but long story short, there are some combinations of clicking around that can cause the PHP to fight the JS and null the cookie.)

Then in the page header:

<?php
if(!isset($_COOKIE['theme'])) { $theme = "light"; } else { $theme = $_COOKIE['theme']; }
if($theme=="light") {
    $curStyle = "Styles/light.css";
    $curTitle = "light";
    $altStyle = "Styles/dark.css";
    $altTitle = "dark";
} else {
    $curStyle = "Styles/dark.css";
    $curTitle = "dark";
    $altStyle = "Styles/light.css";
    $altTitle = "light";
}
?>

Then to make the active stylesheet always first in the list:

<link rel="stylesheet" href="<?php echo $curStyle ?>" type="text/css" title="<?php echo $curTitle ?>" />
<link rel="stylesheet" href="<?php echo $altStyle ?>" type="text/css" title="<?php echo $altTitle ?>" />

That eliminates the flashing because the active stylesheet is always first.

Simple stuff, but maybe it will save someone some time.

Richard

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.