Original demo link address
Front end skin N schemes
❝
Recently, I am doing a website skin change, which is to switch the theme. So how do you switch the color of the theme? The following is the realization of the site skin and skin based on the development of some schemes to share with you, I hope you can do similar needs when some reference.
❞
Overwrite style implementation
// light
$color-brand1: #ffcd32;
$fill-1: #fff !default;
$color-text: #3c3c3c;
$color-text-1: # 757575;
$color-text-2: # 222;
// dark
$dark-fill-1: # 222 !default; / / brand color
$dark-color-text: #fff;
$dark-color-text-1: rgba(255, 255, 255, 03.);
$dark-color-text-2: $color-brand1;
Copy the code
// page usage
<style lang="scss">
@import "./assets/scss/index.scss";
[data-theme="dark"] {
body {
background: $dark-fill-1;
}
.reaconmend .reaconmend-list .item .name {
color: $dark-color-text;
}
.reaconmend .reaconmend-list .item .desc {
color: $dark-color-text-1;
}
.header .text {
color: $dark-color-text-2;
}
}
</style>
Copy the code
“disadvantages“
The style is not easy to manage, the search style is complex, the development efficiency is low, the expansion is poor, the maintenance cost is high, the multi-person collaboration communication is troublesome.
Sass variable implementation
// variable.scss
/ / light color
$colors-light: (
fill-1: #fff.
text: #3c3c3c.
text-1: # 757575.
text-2: # 222.
);
/ / dark
$colors-dark: (
fill-1: # 222.
text: #fff.
text-1: rgba(255, 255, 255, 03.),
text-2: #ffcd32.
);
Copy the code
// mixin.scss
/ / the background color
@mixin bg-color($key) {
background-color: map-get($colors-light, $key);
[data-theme="dark"] & {
background-color: map-get($colors-dark, $key);
}
}
// textcolor
@mixin text-color($key) {
color: map-get($colors-light, $key);
[data-theme="dark"] & {
color: map-get($colors-dark, $key);
}
}
Copy the code
// page usage
<style lang="scss" rel="stylesheet/scss">
@import ".. /.. /.. /assets/scss/variable.scss";
@import ".. /.. /.. /assets/scss/mixin.scss";
.reaconmend-list {
.list-title {
height: 40px;
line-height: 40 px;
text-align: center;
@include text-color(text-1);
}
}
</style>
Copy the code
Sass Maps: $map-get($map,$key) Sass Maps: $map-get($map,$key)
❝
Maps can be viewed as a collection of key-value pairs, and keys are used to locate values that have no CSS equivalent. Unlike Lists Maps must be surrounded by parentheses and key-value pairs are easily separated. Keys and values in Maps can be any object in SassScript. Maps, like Lists, primarily serve Sassscript functions, such as the map-get function, which is used to find keys, The map-merge function is used to merge maps with newly added keys. The @each command adds styles to each key pair in a map. Maps can be used anywhere Lists are available. A Map is automatically converted to a List in the List function (key1: value1, key2: value2), and not vice versa. (Courtesy of Soledad)
❞
“Use SCSS variable peels compared to overlay styles“
- More extensible
- The logic of skin is convergent
Generate multiple skins CSS
Using the override style implementation and SCSS variable implementation compiles multiple skin styles into a CSS file, which can be very large if there are multiple skin styles. In order to solve such a problem, it is natural to come up with the implementation of split SCSS: implementation scheme, through compilation tools and construction tools to compile a number of skin CSS, through JS dynamic link corresponding skin style
// dynamic processing
var theme = /\bt=(\w+)/.exec(location.search);
theme = theme ? theme[1] : "light";
changeTheme(theme);
function changeTheme(theme) {
var head = document.getElementsByTagName("head") [0];
var link = document.createElement("link");
link.dataset.type = "theme";
link.href = "assets/css/theme-" + theme + "/pages/home/home.css";
link.rel = "stylesheet";
link.type = "text/css";
head.appendChild(link);
}
Copy the code
CSS variable implementation
// variable.scss
// Default variable
:root {
--fill-1: #fff;
--text: #3c3c3c;
--text-1: # 757575;
--text-2: # 222;
--font-size-large: 18px;
--font-size-large-x: 22px;
--font-size-medium: 14px;
--font-size-medium-x: 16px;
--font-size-small-s: 10px;
--font-size-small: 12px;
}
// Dark variables
[data-theme="dark"] {
--fill-1: # 222;
--text: #fff;
--text-1: rgba(255, 255, 255, 0.3);
--text-2: #ffcd32;
}
Copy the code
Do import use of CSS variables on the page
// page usage
@import ".. /.. /assets/scss/variable.scss";
.header {
position: relative;
height: 70px;
text-align: center;
font-size: 0;
.text {
display: inline-block;
vertical-align: top;
line-height: 70px;
font-size: var(--font-size-large);
color: var(--text-2);
}
}
Copy the code
Specific implementation effect:
❝
Problem: CSS variables have compatibility issues
❞
CSS variable compatibility is as follows:
Although most of the major browsers are now compatible, there are more compatibility issues to consider:
CSS variable compatibility implementation -1
❝
Add postCSs-custom-properties plugin dependencies to CSS variables: npm install postcss-custom-properties –save-dev npm install postcss-loader –save-dev
❞
Create postcss.config.js in the root directory to add the following configuration:
const postcssCustompProperties = require("postcss-custom-properties");
module.exports = {
plugins: [
postcssCustompProperties({
importFrom: "src/assets/scss/variable.scss"
})
]
};
Copy the code
Postcss compiles CSS custom variables directly toTo determine the value
And theNot retain
. That’s when you needPostcss plug-in
To reserve these custom variables for us, usepostcss-custom-propertiesThe effect is as follows:
- Advantages: Generates a set of CSS corresponding to CSS variables
- Disadvantages: CSS variables are generated at build time, skinning is not generated at run time.
After skin change style:
CSS variable compatibility implementation -2
First, you need to create a JS file to store common CSS variables, and store the CSS variables to be defined in this JS file, such as (variable.js).
// variable.js
// Font variable
const baseSize = {
"--font-size-large-x": "22px".
"--font-size-large": "18px".
"--font-size-medium": "14px".
"--font-size-medium-x": "16px".
"--font-size-small-s": "10px".
"--font-size-small": "12px".
};
/ / light color
export const lightTheme = {
"--fill-1": "#fff".
"--text": "#3c3c3c".
"--text-1": "# 757575".
"--text-2": "# 222".
. baseSize,
};
/ / dark
export const darkTheme = {
"--fill-1": "# 222".
"--text": "#fff".
"--text-1": "Rgba (255, 255, 255, 0.3)".
"--text-2": "#ffcd32".
. baseSize,
};
Copy the code
Pages use CSS variables, such as:
<style lang="scss">
.text {
display: inline-block;
vertical-align: top;
line-height: 70px;
font-size: var(--font-size-large);
color: var(--text-2);
}
</style>
Copy the code
Install csS-vars-ponyfill
❝
Css-vars-ponyfill: client-supported Ponyfill for CSS custom properties (aka “CSS variables”) in both traditional and modern browsers. (Please refer to the official website: csS-Vars-ponyfill for specific usage and concepts.)
❞
Encapsulate the switch theme js and do the initial call in main.js
// theme.js
import { lightTheme, darkTheme } from ".. /src/assets/js/variable";
import cssVars from "css-vars-ponyfill";
export const initTheme = (theme) = > {
document.documentElement.setAttribute("data-theme", theme ? "light" : "dark");
cssVars({
watch: true.Ponyfill is called when the disabled or href attribute of its
or
variables: theme ? lightTheme : darkTheme, // variables A collection of custom attribute name/value pairs
onlyLegacy: false.// false Compiles CSS variables to browser-recognized CSS styles by default. True Compiles CSS variables to browser-recognized CSS styles when the browser does not support CSS variables
});
};
Copy the code
Called in the toggle theme button component
Summary: CSS custom attributes + CSS-vars-ponyfill
preview
❝
If you are careful, you must have noticed that the CSS variable has been compiled into a browser-recognized CSS style.
❞
ElementUI implementation
Official implementation explanation
- Start by replacing the CSS values related to colors in the default theme file with keywords: github.com/ElementUI/t…
- Generate a series of color values based on the theme color selected by the user: github.com/ElementUI/t…
- Replace the keyword with the corresponding color value you just generated: github.com/ElementUI/t…
- Add it directly to the page
style
Tag to fill in the generated style:Github.com/ElementUI/t…
Implemented link reference: juejin.cn/post/684490…
Less online compilation implementation
According to “less” can directly compile “less variable” implementation steps are as follows:
// variable.lessdefinelessvariable
// Public font
@font-size-large-x: 22px;
@font-size-large: 18px;
@font-size-medium: 14px;
@font-size-medium-x: 16px;
@font-size-small-s: 10px;
@font-size-small: 12px;
/ / light color
@fill-1: #fff;
@text: #3c3c3c;
@text-1: #757575;
@text-2: #222;
// Page usage example:
/ / the following.textthecssHere it is, at sign herefont-size-largeAnd @ text -2The less variable:
.text {
display: inline-block;
vertical-align: top;
line-height: 70px;
font-size: @font-size-large;
color: @text-2;
}
Copy the code
When the skin button is clicked, load less. Js directly, as shown below
<template> <div class="header"> <div class="text"> <div role="switch" class="switch" :class="theme === true? 'is-checked' : ''"> <input type="checkbox" class="switch-input" /> <span class="switch-core" @click="changeTheme"></span> </div> </div> </template>Copy the code
<script> import { lightTheme, darkTheme } from ".. /.. /assets/js/variable"; export default { name: "m-header", data() { return { theme: true }; }, methods: { changeTheme() { this.theme = ! this.theme; / / call
less.modifyVars
Method to change the variable value window.less. ModifyVars (this.theme? lightTheme : darkTheme); } }, mounted() {} }; </script>
Variable.js is defined because the switch effect will only take effect once if you place the less variable directly in modifyVars, so use the corresponding less variable based on the state of the switch.
/ / light color
export const lightTheme = {
"@fill-1": "#fff".
"@text": "#3c3c3c".
"@text-1": "# 757575".
"@text-2": "# 222".
};
/ / dark
export const darkTheme = {
"@fill-1": "# 222".
"@text": "#fff".
"@text-1": "Rgba (255, 255, 255, 0.3)".
"@text-2": "#ffcd32".
};
Copy the code
Then click on the color block to test and find that it does not work, this is why? It then looks at its documentation and finds all of the following less style tags and synchronously creates style tags using compiled CSS. This means that we must import all less in the code as link, so that less. Js can be compiled on the browser side.
I’m using vue here, so I’m just going to takeless
The files are inpublic
Directory, and then directly into HTML:
Click the toggle button to see that the background and color have indeed changed
❝
Note: When using less to implement peels, pay attention to where the less file is written in HTML, otherwise it may be interfered by other CSS files and the peels will fail. If the less file is particularly large, there can be compilation performance issues.
❞
Extension – Picture switching
The above scheme is only for background-color and color skin, if the image to skin what to do?
“Image switching“
There are also lots of placeholders and other images that change from theme to theme. By introducing all images and using file names to distinguish the images that correspond to different themes. Click on the switch theme, switch to the theme of the corresponding file, you can realize the picture switch.
// Page implementation
<template>
<div class="header">
<div class="text">Baby dinosaur skin</div>
<div role="switch" class="switch" :class="theme === true ? 'is-checked' : ''">
<input type="checkbox" class="switch-input" />
<span class="switch-core" @click="changeTheme"></span>
</div>
</div>
</template>
<script>
import { initTheme } from ".. /.. /theme";
import bus from ".. /.. /bus";
export default {
name: "m-header".
data() {
return {
theme: true.// false dark theme
avatar: ""
};
},
methods: {
changeTheme() {
this.theme = !this.theme;
initTheme(this.theme);
this.setThemeValue(this.theme);
bus.$emit("changeTheme".this.theme);
},
setThemeValue(theme) {
theme = theme ? "light" : "dark";
this.avatar = require(`@/assets/images/logo-${theme}.jpeg`);
}
},
created() {
this.setThemeValue(this.theme);
}
};
</script>
Copy the code
When you click to switch the theme, a changeTheme event will be emitted. Each component receives the changeTheme event and will reassign the value to the image, thus achieving the effect of switching the image.
The last
Thank you very much for taking time out of your busy schedule to finish reading this article 🙂 if you have any questions or suggestions, you can exchange more, original article, writing is limited, talent is shallow, if there is anything wrong in the article, please feel free to tell me. Well, the end of this article, I hope to help you 🙂
reference
Sass website: www.sasscss.com/documentati… Less official website: www.html.cn/doc/less/us… CSS variables: developer.mozilla.org/zh-CN/docs/… Css-vars-ponyfill:www.npmjs.com/package/css… Element – the UI: element. The eleme. Cn / # / useful – cn/the… Postcss:www.npmjs.com/package/pos… Postcss-custom-properties:github.com/postcss/pos… Talk about front-end peels: juejin.cn/post/684490…