Search code examples
htmlcsscss-selectorscss-variables

How to create an HTML document that allow switch themes using pure HTML and CSS?


How to create a document that allow switch themes using HTML and CSS ? (without JavaScript)

I created simple HTML document :

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <style type="text/css">
        :root { --bg-color: lightgreen; }
        * { background-color: var(--bg-color); }
        /* You can add lines here. */
    </style>
</head>
<body>
    <div>
        <h2 id="theme-1">Theme 1</h2>
        <a href="#theme-1">Theme 1</a>
    </div>
    <div>
        <h2 id="theme-2">Theme 2</h2>
        <a href="#theme-2">Theme 2</a>
    </div>
    <div>
        <h2 id="no-theme">No theme</h2>
        <a href="#no-theme">No theme</a>
    </div>
</body>
</html>

with <style> tag.

I tried to insert this CSS code :

        :has(#theme-1:target) { --bg-color: red; }
        :has(#theme-2:target) { --bg-color: blue; }

but no one browser support :has selector.

Then I tried to insert this :

        #theme-1:target { --bg-color: red; }
        #theme-2:target { --bg-color: blue; }

but it doesn't change background-color of <body>. It change <h2> tags only.

So, how to switch between themes ? Is it possible at all ?


Solution

  • It is possible: You have to nest everything (or at least everything that should depend on theme). e.g:

    <html lang="en">
      <head>
        <title>Document</title>
        <style type="text/css">
          #theme-1:target{
            background: red;
          }
          #theme-1:target h2{
            font-family: "Verdana";
          }
          #theme-2:target{
            background: blue;
          }
          #theme-2:target h2{
            font-family: "Times New Roman";
          }
        </style>
      </head>
      <body>
        <div id="theme-1"><div id="theme-2">
          <h2>Theme 1</h2>
          <a href="#theme-1">Theme 1</a>    
          <h2>Theme 2</h2>
          <a href="#theme-2">Theme 2</a>    
          <h2 id="no-theme">No theme</h2>
          <a href="#no-theme">No theme</a>
        </div></div>
      </body>
    </html>