preface
- 2019 multi-brand product adaptation summary Vue project theme color adaptation, read this article is enough
- H5 page aged adaptation
Subject switch
In business, there is a need to change the page theme style. Common implementation schemes include: replace CSS links, modify className, use less. ModifyVars, and modify CSS variables.
1. Solution 1: Add a special class name to the body
How it works: By changing the class name of the body tag, the CSS scope is used to switch the theme
1.1 Implementation Procedure
1.1.1 Create page interfaces and styles
In this example, Umi is used to build a project. Assume that the theme is “Christmas Activities”. The HTML code is as follows
// pages/index/index.tsx import './index.less'; export default function IndexPage() { return ( <div className="page-index"> <div className="banner"></div> <section <h1 > <p className="desc"> </h1> <p className="desc"> </h1> <p className="desc"> Can be on the spot consumption of mobile phone can be installments 00 down payment 0 interest for old new, the highest can be as low as 4000 yuan contact phone 18103414888 store welcome the New Year with id card into the store get 100 yuan phone fee, go home for the New Year. Details into the shop to consult. </p> <button className="button"> }Copy the code
The style code is as follows
.page-index { .banner { height: 257px; width: 100%; background-size: cover; background-color: #cccccc; background-repeat: no-repeat; background-position: center; } .content { padding: 20px; } .button { border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: block; width: 100%; font-size: 16px; }}Copy the code
1.1.2 Extract the style file
Will need to customize background-image,background-color, color and so on to create theme files, has Christmas as an example
// assest/theme/normal.less .normal { background-color: #f1f1f1; .banner { background-image: url('.. /images/normal.jpeg'); } .content{ .title { color: #000; } color: #333333; .button{ background-color: #4caf50; }}}Copy the code
// assest/theme/christmas.less .christmas { background-color: lightpink; .banner { background-image: url('.. /images/christmas.jpeg'); } .content{ .title { color: #fff; } color: #ffffff; .button{ background-color: red; /* Green */ } } }Copy the code
1.1.3 Introduce theme files in global.less
// src/global.less
@import './assest/theme/normal';
@import './assest/theme/christmas';
Copy the code
1.1.4 Add a class to the body in HTML in the project entry app.ts
// app.ts // Default normal and Christmas themes, Modify the className switch value subject const className = 'Christmas' document. The getElementsByTagName (' body') [0]. The className = className.Copy the code
1.2 Preview page Results
ClassName = ‘normal’ className = ‘Christmas’
1.3 conclusion:
- Advantages: Simple implementation and easy to understand
- Disadvantages:
- When you need to write multiple theme files with a large number of pages, you need to pay attention to style naming conflicts
- You can’t use CSS Modules, or you can’t use className hashing
Consider: why not use variables if you use less?
2. Scheme 2: Use the less variable
2.1 Implementation Procedure
2.1.1 Modifying the Theme file in Solution 1
Change color values to variables
// noemal.less @primary-color: #4caf50; @bg-color: #f1f1f1; @title-color: #000000; @text-color: #333333; @banner-images: url('.. /images/normal.jpeg'); .normal { background-color: @bg-color; .banner { background-image: @banner-images; } .content { color: @text-color; .title { color: @title-color; } .button { background-color: @primary-color; }}}Copy the code
// christmas.less @primary-color: red; @bg-color: lightpink; @title-color: #ffffff; @text-color: #ffffff; @banner-images: url('.. /images/christmas.jpeg'); .christmas { background-color: @bg-color; .banner { background-image: @banner-images; } .content { .title { color: @title-color; } color: @text-color; .button { background-color: @primary-color; }}}Copy the code
This is not fundamentally different from what we did before, except that we write values as variables
Consider: it would be perfect if you could dynamically change the value of a variable like JS!
2.1.2 Replanning the theme file theme.less
// theme.less
@primary-color: red;
@bg-color: lightpink;
@title-color: #ffffff;
@text-color: #ffffff;
@banner-images: url('../images/christmas.jpeg');
body{
background-color: @bg-color;
}
.banner {
background-image: @banner-images;
}
.content {
.title {
color: @title-color;
}
color: @text-color;
.button {
background-color: @primary-color;
}
}
Copy the code
Where does the theme. Less file go?
In order not to be compiled by Webpack when the project is packaged, we put the style file in the root directory public (public/style/theme.less) and set public as a static repository. In Umi’s case, we need to change it in umirc.ts
export default defineConfig({
...
publicPath: '/public/'
...
})
Copy the code
Let’s create a theme summary public/style/index.less to import different page styles
// @import "./night.less"; @import "./theme.less";Copy the code
Importing the index.less style file into the HTML file (Umi For details about how to modify the default HTML template, see the OFFICIAL DOCUMENT HTML Template
<! doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui" /> <title>Your App</title> </head> <body> <link rel="stylesheet/less" type="text/css" href=".. /.. /public/style/index.less" /> <div id="root"></div> </body> </html>Copy the code
To modify variable values
2.1.3 JS control variable values
Install less relies on NPM to install less, creating a utility function utils/index.ts to switch themes
import less from 'less'; export const changeTheme = (themeOption: Record<string, string>) => {less.modifyVars({// call the 'less.modifyVars' method to change the variable value... ThemeOption,}). Then (() = > {the console. The log (' success '); })}Copy the code
Prespecify several sets of theme json objects and call the changeTheme function when appropriate, as used in app.ts for example:
import {changeTheme} from './utils/index'; // Default const defaultTheme = {'@primary-color': '#4caf50', '@bg-color': '#f1f1f1', '@title-color': '#000000', '@text-color': '#333333', '@banner-images': "url('.. // Christmas const christmasTheme = {'@primary-color': 'red', '@bg-color': 'lightpink', '@title-color': '#ffffff', '@text-color': '#ffffff', '@banner-images': "url('.. /images/ Christmas.jpeg ')",} // Dark mode const darkTheme = {'@primary-color': 'gold', '@bg-color': '#000000', '@title-color': '#ffffff', '@text-color': '#FFFFFF', '@banner-images': "url('.. /images/normal.jpeg')",} // Call the changeTheme method changeTheme({... christmasTheme })Copy the code
2.2 Preview page effect
2.3 conclusion:
Advantages:
- Jiashan can control the color flexibly
- Can preset several sets of general theme collocation, also support user customization
Disadvantages:
- Projects need to plan theme styles in advance, theme variable values need to be separated from general style files, and development and maintenance costs are high
Think: How to switch themes more gracefully?
- The topic file uses the CDN and changes the CDN file at a specific time
- The back-end interface returns JSON for the color value variable
- Switch themes at fixed times using timestamps
1640361599000 let currentTheme = defaultTheme if (new Date().valueof () > 1640361599000) { currentTheme = christmasTheme } else { currentTheme = defaultTheme } changeTheme(currentTheme)Copy the code
- Gets the current time to determine whether it is day or night
let currentTheme = defaultTheme
const hours = new Date().getHours()
if (hours > 8 && hours < 20) {
currentTheme = defaultTheme
} else {
currentTheme = darkTheme
}
changeTheme(currentTheme)
Copy the code
5. Based on the current system mode
const mediaQuery = window.matchMedia('(prefers-color-scheme: Dark)') function darkModeHandler() {if (mediaQuery.matches) {console.log(' now in dark mode ') changeTheme(darkTheme)} else { Console. log(' now light mode ') changeTheme(defaultTheme)}} // Determine the current mode darkModeHandler() // listen for mode changes mediaQuery.addListener(darkModeHandler)Copy the code
3. Scheme 3: Native CSS variables,
Take aging adaptation as an example
3.1 Implementation Procedure
3.1.1 HTML structure and style of the page
H5 page pixel adaptation (REM scheme), added in global.css
: root {28 px: - the font size - 2.8 rem; - the font size - 32 p: 3.2 rem. - the font size - 36 px: 3.6 rem. - the font size - 40 px: 4.0 rem. --220PX: 22rem; - 514 px: 51.4 rem; } HTML {font-size: 31.25%; } body{ font-size: var(--font-size-28PX); }Copy the code
Create a file called pages/eleder/index.tsx
import style from './index.less'; import {ClockCircleOutlined} from '@ant-design/icons' import {Button} from 'antd' export default function IndexPage() { return ( <div className={style.pageElder}> <div className={style.banner}></div> <section className={style.content}> <h1 </h1> <p className={style.title}> </h1> <p className={style.desc}> Can be on the spot consumption of mobile phone can be installments 00 down payment 0 interest for old new, the highest can be as low as 4000 yuan contact phone 18103414888 store welcome the New Year with id card into the store get 100 yuan phone fee, go home for the New Year. Details into the shop to consult. </p> <ul className={style.list}> <li className={style.item}><ClockCircleOutlined style={{fontSize: '38px'}}/></li> <li className={style.item}><ClockCircleOutlined style={{fontSize: '38px'}}/></li> <li className={style.item}><ClockCircleOutlined style={{fontSize: '38px'}}/></li> <li className={style.item}><ClockCircleOutlined style={{fontSize: '38px'}}/></li> <li className={style.item}><ClockCircleOutlined style={{fontSize: '38px'}}/></li> <li className={style.item}><ClockCircleOutlined style={{fontSize: '38 px'}} / > < / li > < / ul > < button className = {style. The button} > immediately join < / button > < / section > < / div >). }Copy the code
Create a style file called pages/eleder/index.tsx
.pageElder { .banner { height: var(--514PX); width: 100%; background-size: cover; background-color: #cccccc; background-repeat: no-repeat; background-position: center; background-image: url(".. /.. /.. /public/images/normal.jpeg"); } .content { padding: 20px; color: #333333; .title{ color: #000000; font-size: var(--font-size-40PX); } .desc { font-size: var(--font-size-28PX); } .list{ list-style: none; display: flex; padding: 0; margin: 20px 0; flex-wrap: wrap; .item { border: 1px dashed #ccc; display: inline-block; margin: 10px 0; width: var(--220PX); text-align: center; } } } .button { border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: block; width: 100%; font-size: var(--font-size-32PX); background-color: #4caf50; }}Copy the code
3.1.2 Creating tool Functions for modifying CSS variables
Add in utils/index.ts
// Modify the CSS variable export const setCssVar = (themeOption: {[x: string]: any; }) => { const root = document.querySelector(':root') as HTMLScriptElement; Object.keys(themeOption).forEach((key)=> { root.style.setProperty(key, themeOption[key]); })}Copy the code
3.1.3 Preset variable values and switch when appropriate
Add the following code to pages/eleder/index.ts
import {setCssVar} from "@/utils"; Import {useState} from 'react'; / / the default variable value const normal = {' - the font size - 28 px ':' 2.8 rem ', '- the font size - 32 pixels' :' 3.2 rem ', '- the font - size - 36 pixels' : '3.6 rem', '-- the font size - 40 px' : '4.0 rem', '- 220 px' : '22 rem', '- 514 px' : '51.4 rem'} const elder = {' - the font size - 28 px ': '4.0 rem', '-- the font size - 32 pixels' :' 4.8 rem ', '- the font - size - 36 pixels' :' 5.0 rem ', '- the font size - 40 px' : '5.6 rem', '- 220 px' : '30rem', '--514PX': '73.4rem'} export default function IndexPage() {const [toggle, SetToggle] = useState< Boolean >(true) // Toggle const change = () => {toggle? setCssVar(elder):setCssVar(normal) setToggle(! Toggle)} return (<div className={style.pageElder}> <Button size="small" onClick={change}> </Button> <div className={style.banner}></div> ... </div> ); }Copy the code
3.2 Page effect preview
4. Small program theme switch
Small program switching and the theme of the H5 page is different, small program with no window and document attributes, so the document before the getElementsByTagName (‘ body ‘) [0]. Can’t use the className = className
The less applet is compiled to recognize ACSS, so it cannot be processed using less variables.
4.1 Technical Principles
Let’s use CSS native support for variables, starting with the following code
// index.acss
.title {
color: var(--title-color, #000000);
}
Copy the code
Axml <view className="title" style="--title: #FFFFFF"> </view>Copy the code
We can add a variable “–title-color” to a font color and give it a default value of #000000. Then we can change the font color by changing the value of –title-color inline with the style
4.2 Implementation Procedure
We used alipay mini program framework miniU to create the project, please refer to the official document of Alipay MiniU for specific creation
4.2.1 Create page index.axml
// index.axml file, <view style={{themeStyle}} className="page-index" >< view className="banner"></view> <view ClassName ="content"> <view className="title"> </view> <view className="desc"> Can be on the spot consumption of mobile phone can be installments 00 down payment 0 interest for old new, the highest can be as low as 4000 yuan contact phone 18103414888 store welcome the New Year with id card into the store get 100 yuan phone fee, go home for the New Year. Details into the shop to consult. </view> </view> </view> </view>Copy the code
4.2.2 Page Style index.less
.page-index {
.banner {
height: 257px;
width: 100%;
background-size: cover;
background-color: #cccccc;
background-repeat: no-repeat;
background-position: center;
background-image: var(--banner-images, url('https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/70967f6ec4ac40bb9b17a673849e9fc6~tplv-k3u1fbpfcp-watermark.image?'));
}
.content {
padding: 20px;
.title {
color: var(--title-color, #000000);
}
.desc {
color: var(--text-color, #333333);
margin-bottom: 50rpx;
}
}
.button {
border: none;
color: white;
text-align: center;
text-decoration: none;
display: block;
width: 100%;
background: var(--primary-color, #4caf50);
}
}
Copy the code
We define –banner-images, –title-color, –text-color, –primary-color
Holdings data flow
We use MiniU Data stream processing, and references use global variables
// index.js import { createPage } from '@miniu/data'; Page( createPage({ mapGlobalDataToData: { themeStyle: (globalData) => { return globalData.themeStyle; ,}}}));Copy the code
To use themeStyle, you need to define it in app.js and change the color value in onLaunch
import {createApp, setGlobalData} from '@miniu/data'; import {getSkinSettings} from './service/index'; App( createApp({ defaultGlobalData: { count: 50, themeStyle: Const res = await getSkinSettings(); // Define global variables themeStyle}, async onLaunch(options) {const res = await getSkinSettings(); // Simulate getting the color value this.setthemestyle (res.data) from the backend; // Change color value}, setThemeStyle({primaryColor = '#4caf50', bgColor = '# f1f1F1 ', titleColor = '#000000', textColor = '#333333', bannerImages = 'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/70967f6ec4ac40bb9b17a673849e9fc6~tplv-k3u1fbpfcp-watermark.image?', }) { setGlobalData((globalData) => { globalData.themeStyle = ` --primary-color: ${primaryColor}; --bg-color: ${bgColor}; --title-color: ${titleColor}; --text-color: ${textColor}; --banner-images: url('${bannerImages}'); `; }); SetBackgroundColor ({backgroundColor: bgColor,}); }}));Copy the code
4.2.4 Simulating interface requests
// service/index.js export const getSkinSettings = () => { const themeData = { primaryColor: 'red', bgColor: '#ffb6c1', titleColor: '#ffffff', textColor: '#ffffff', bannerImages: 'https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dd9dd0126a404dcb8a943dfab864c1cd~tplv-k3u1fbpfcp-watermark.image?', }; Return new Promise((resolve, reject) => {setTimeout(() => {const resData = {code: 200, data: { ... themeData, }, }; If (resdata.code === 200) {resolve(resData); } else {reject({code: resdata.code, message: 'Network error'}); }}, 500); }); };Copy the code
Inserts variable values in the root node of the page
Variables are being used in child nodes
4.3 Effect Preview
eggs
One line of code to achieve gray mode (National memorial Day, National Disaster Day, 512 Memorial Day, mourning martyrs)
Such as:
html {
-webkit-filter: grayscale(.95);
}
Copy the code
The source address
H5 source: gitee.com/ssjuanlian/…
Small program source: gitee.com/ssjuanlian/…