Several schemes of topic switching in Web front end

Welcome to my official account, Talk, for my latest article:

1, Foreword

This article will introduce several common schemes of topic switching in the Web front end, and the sample code is based on the React framework. show you the code!

2, Scenario 1: predefined themes

In this scenario, two themes of light color and dark color are predefined, and there can be two implementation schemes.

Scenario 1: CSS attribute override

This scheme makes use of the characteristics of css multi-layer style accurate matching, and realizes the theme switching through style coverage.
First, you need to set a class in the root element of the application and assign the corresponding value to the class when switching topics. Take theme1/theme2 as an example.

h2 {
  color: brown;
}
button {
  background-color: yellow;
}
.theme2 h2 {
  color: blue;
}
.theme2 button {
  background-color: green;
}
import './combine.css';
export default function App() {
  const [theme, setTheme] = useState('theme1');
  return (
    // Toggles the class to which the root element is applied
    <div className={theme}>
      <h2>{theme}</h2>
      <button onClick={() => {
        setTheme(theme => { if (theme === 'theme1') return 'theme2'; return 'theme1' })
      }}>Switch theme</button>
    </div>
  );
}

Scheme 2: css variable replacement

The idea of this scheme is similar to that of scheme 1, except that it is used css variable To define the theme color.
First, define a dataset on the root element of the page: < HTML lang = "en" data theme = "Theme1" >.
Then define variable values for different topics:

<style id="theme-var">
  :root {
        --font-color: brown;
        --button-color: yellow;
      }
  :root[data-theme=theme2] {
    --font-color: blue;
    --button-color: green;
  } 
</style>
h2 {
  color: var(--font-color, black)
}
button {
  background-color: var(--button-color, gray);
}
import './var.css';
export default function App() {
  const [theme, setTheme] = useState('theme1');
  return (
    <div>
      <h2>{theme}</h2>
      <button onClick={() => {
        const doc = document.documentElement;
        const newTheme = theme === 'theme1' ? 'theme2' : 'theme1';
        // Set the dataset of the page root element
        doc.dataset.theme = newTheme;
        setTheme(newTheme);
      }}>Switch theme</button>
    </div>
  );
}

3, Scenario 2: allow users to customize themes

The biggest difference between this scenario and scenario 1 is that CSS properties and variables cannot be predefined. Generally, it is necessary to match the interface to realize the function of dynamic replacement. The following example only demonstrates the principle and ignores the processing of interface data.

Scheme 1: full replacement of CSS

This scheme is relatively simple and crude. You need to package all css of the page together and put it in the style tag with predefined ID. when switching topics, you need to replace all css.

// Assume that the following css is a string obtained from the interface
const themeAll1 = 'h2 {color: brown;} button {background-color: yellow;}'
const themeAll2 = 'h2 {color: blue;} button {background-color: green;}'
export default function App() {
  const [theme, setTheme] = useState('Topic 1');
  return (
    <div>
      <h2>{theme}</h2>
      <button onClick={() => {
        // Replace the contents of the style label
        if (theme === 'Topic 1') {
          document.getElementById('theme-all').innerText = themeAll2;
          setTheme('Topic 2')
        } else {
          document.getElementById('theme-all').innerText = themeAll1;
          setTheme('Topic 1')
        }

      }}>Switch theme</button>
    </div>
  );
}

Scenario 2: replace CSS variables

Scheme 1 is relatively simple and crude, and the amount of data is relatively large. have access to css variable To optimize, extract the theme color variable and put it under the root pseudo class. When switching themes, you only need to dynamically set the value of the css variable in the style tag.

<style id="theme-var">
  :root {
    --font-color: brown;
    --button-color: yellow;
  }
</style>
h2 {
  color: var(--font-color, black)
}
button {
  background-color: var(--button-color, gray);
}
import './var.css';
// Suppose the following css is a string obtained from the interface
const themeVar1 = ':root {--font-color: brown; --button-color: yellow;}'
const themeVar2 = ':root {--font-color: blue; --button-color: green;}'
export default function App() {
  const [theme, setTheme] = useState('Topic 1');
  return (
    <div>
      <h2>{theme}</h2>
      <button onClick={() => {
        // Replace the contents of the style label
        if (theme === 'Topic 1') {
          document.getElementById('theme-var').innerText = themeVar2;
          setTheme('Topic 2')
        } else {
          document.getElementById('theme-var').innerText = themeVar1;
          setTheme('Topic 1')
        }
      }}>Switch theme</button>
    </div>
  );
}

6, Summary

This paper introduces four common topic switching schemes, of which the last scheme is the most flexible and can cooperate with API to expand an unlimited number of topics. For the more common light plus dark theme mode, you can choose the second scheme. What they have in common is that they use css variables to extract theme colors, which is very elegant.

Keywords: Front-end less sass css

Added by jackinva on Mon, 03 Jan 2022 18:26:38 +0200