# DarkMode adaptation guide

HBuilder X 3.6.9+ support

Dark mode (Dark Mode), also known as night mode or dark mode, is a high-contrast, or inverse mode display mode. It is a high-contrast mode that is good for viewing the phone in a dark environment. The dark mode of uni-app is a batch of configurations and APIs to help developers complete the dark mode of their own applications. Developers can refer to this article to implement the dark mode of their own applications.

Plugin market example project: https://ext.dcloud.net.cn/plugin?name=hello-darkmode

# Open DarkMode

In the manifest.json configuration, part of the configuration of the application can be configured in the form of variables, and the colors or icons under different themes are defined in the variable configuration file. The configuration of each platform is as follows:

# app-plus

Configure in manifest.json -> app-plus:

  1. Configure darkmode:true
  2. Configure themeLocation, specify the variable configuration file theme.json path, for example: add theme.json under the root directory, you need to configure "themeLocation":"theme.json"
  3. Define related variables in theme.json
  4. Reference variables starting with @ in pages.json
  5. Overall configuration
     "app-plus" : {
    		"darkmode" : true,
    		"themeLocation" : "theme.json" // 如果 theme.json 在根目录可省略
     }
    

# iOS security area adaptation

  • Enable safe area occupancy

    Add "safearea" under the "app-plus" node of the manifest.json file to adapt to the safe area of iOS, "background" corresponds to the background color outside the safe area in normal mode, and "backgroundDark" corresponds to the color outside the safe area in dark mode background color

    "app-plus" : {
    	"safearea": { //iOS平台的安全区域
    		"background": "#ffffff",
    		"backgroundDark": "#2f0508", // HX 3.1.19+支持
    		"bottom": {
    			"offset": "auto"
    		}
    	}
    }
    
  • Turn off safe area occupancy

    Set "offset" to "none" to close the safe area occupancy. Note: When the security area occupancy is turned off, the content of the Notch page may be blocked by the "homeBar", which needs to be adapted by itself. For details, please refer to the document iOS Notch Adaptation

    "safearea": {
    		"bottom": {
    				"offset": "none"
    		}
    }
    

Notice:

  • Only supported on iOS 13+, Android 10+ devices
  • Requires cloud packaging to take effect

# h5

Configure in manifest.json -> h5:

  1. Configure darkmode:true
  2. Configure themeLocation, specify the variable configuration file theme.json path, for example: add theme.json under the root directory, you need to configure "themeLocation":"theme.json"
  3. Define related variables in theme.json
  4. Reference variables starting with @ in pages.json
  5. Overall configuration
     "h5" : {
    		"darkmode" : true,
    		"themeLocation" : "theme.json" // 如果 theme.json 在根目录可省略
     }
    

# mp-weixin

Configure in manifest.json -> mp-weixin:

  1. Configure darkmode:true
  2. Configure themeLocation, specify the variable configuration file theme.json path, for example: add theme.json under the root directory, you need to configure "themeLocation":"theme.json"
  3. Define related variables in theme.json
  4. Reference variables starting with @ in pages.json
  5. Overall configuration
     "mp-weixin" : {
    		"darkmode" : true,
    		"themeLocation" : "theme.json" // 如果 theme.json 在根目录可省略
     }
    

The properties that support configuration via variables are as follows:

  • Global configuration globalStyle and page support

    • navigationBarBackgroundColor

    • navigationBarTextStyle

    • backgroundColor

    • backgroundTextStyle

    • backgroundColorTop

    • backgroundColorBottom

    • color

    • selectedColor

    • backgroundColor

    • borderStyle

    • list

      • iconPath
      • selectedIconPath

# variable configuration file theme.json

theme.json is used for variable definition related to color theme, you need to configure the path of theme.json in themeLocation first, otherwise the variable configuration cannot be read. Contains the following properties:

Attribute Type Required Description
light Object Yes variable definition in light mode
dark Object Yes Variable definition in dark mode

Examples are as follows:

{
	"light": {
		"navBgColor": "#f8f8f8",
		"navTxtStyle": "black"
	},
	"dark": {
		"navBgColor": "#292929",
		"navTxtStyle": "white"
	}
}

After the definition is completed, it can be referenced at the beginning of @ in the related properties of the global configuration or page configuration in pages.json, for example:

// global configuration
{
  "globalStyle": {
    "navigationBarBackgroundColor": "@navBgColor",
    "navigationBarTextStyle": "@navTxtStyle"
  }
}
// page configuration
{
	"path": "pages/index/index",
	"style":{
		"navigationBarBackgroundColor": "@navBgColor",
		"navigationBarTextStyle": "@navTxtStyle"
	}
}

After the configuration is complete, calling the corresponding api framework will automatically set the properties to display the colors under the corresponding theme.

# Configuration example

pages.json (the example omits configuration items other than those related to the theme)

{
	"globalStyle": {
		"navigationBarBackgroundColor": "@navBgColor",
		"navigationBarTextStyle": "@navTxtStyle",
		"backgroundColor": "@bgColor",
		"backgroundTextStyle": "@bgTxtStyle",
		"backgroundColorTop": "@bgColorTop",
		"backgroundColorBottom": "@bgColorBottom"
	},
	"tabBar": {
		"color": "@tabFontColor",
		"selectedColor": "@tabSelectedColor",
		"backgroundColor": "@tabBgColor",
		"borderStyle": "@tabBorderStyle",
		"list": [
			{
				"iconPath": "@iconPath1",
				"selectedIconPath": "@selectedIconPath1"
			},
			{
				"iconPath": "@iconPath2",
				"selectedIconPath": "@selectedIconPath2"
			}
		]
	}
}

theme.json

{
	"light": {
		"navBgColor": "#f8f8f8",
		"navTxtStyle": "black",
		"bgColor": "#ffffff",
		"bgTxtStyle": "light",
		"bgColorTop": "#eeeeee",
		"bgColorBottom": "#efefef",
		"tabFontColor": "#000000",
		"tabSelectedColor": "#3cc51f",
		"tabBgColor": "#ffffff",
		"tabBorderStyle": "black",
		"iconPath1": "/static/icon1_light.png",
		"selectedIconPath1": "/static/selected_icon1_light.png",
		"iconPath2": "/static/icon2_light.png",
		"selectedIconPath2": "/static/selected_icon2_light.png"
	},
	"dark": {
		"navBgColor": "#292929",
		"navTxtStyle": "white",
		"bgColor": "#1f1f1f",
		"bgTxtStyle": "dark",
		"bgColorTop": "#292929",
		"bgColorBottom": "#1f1f1f",
		"tabFontColor": "#ffffff",
		"tabSelectedColor": "#51a937",
		"tabBgColor": "#292929",
		"tabBorderStyle": "white",
		"iconPath1": "/static/icon1_dark.png",
		"selectedIconPath1": "/static/selected_icon1_dark.png",
		"iconPath2": "/static/icon2_dark.png",
		"selectedIconPath2": "/static/selected_icon2_dark.png"
	}
}

# Get the current theme

If "darkmode": true is declared in the corresponding platform configuration of manifest.json, the return result of uni.getSystemInfo or uni.getSystemInfoSync will contain the theme attribute, and the value is light or dark.

If "darkmode": true is not declared in the corresponding platform configuration of manifest.json, the theme property cannot be obtained (that is, theme is undefined).

# Listen to theme switching events

Two methods are supported:

  1. Write the onThemeChange life cycle in App.vue, it will be triggered when the theme is switched
  2. Use uni.onThemeChange to listen to theme changes, and uni.offThemeChange to cancel the listening

# page css adaptation

css support

In css, it is supported to adapt different themes through the media query prefers-color-scheme, which is consistent with the adaptation method in the web, for example:

/* 一般情况下的样式 start */
.some-background {
	background: white;
}
.some-text {
	color: black;
}
/* 一般情况下的样式 end */

@media (prefers-color-scheme: dark) {
	/* DarkMode 下的样式 start */
	.some-background {
		background: #1b1b1b;
	}
	.some-text {
		color: #ffffff;
	}
	/* DarkMode 下的样式 end */
}