# Page style and layout

uni-app 有 vue 页面、nvue 页面、uvue页面。

  • vue 页面是 webview 渲染的
  • app-nvue 页面是原生渲染的,其样式比 web 会限制更多,另见nvue的css
  • app-uvue 页面是原生渲染的,是 web 的css子集,另见uvue的css

The css of uni-app is basically the same as the css of web. This article does not explain the usage of css. Based on your understanding of css for the web, this article describes some style-related considerations.

本文重点介绍 vue 页面,也就是webview中的样式注意事项。

# css预处理器支持

uni-app 支持less、sass、scss、stylus等预处理器。

参考: css预处理器

# measurement unit

Common css units supported by uni-app include px, rpx

  • px, i.e. screen pixels
  • rpx stands for responsive px, a dynamic unit that adapts to the width of the screen. Based on a 750-wide screen, 750rpx is exactly the width of the screen. When the screen becomes wider, the actual display effect of rpx will be proportionally enlarged, but when the screen width of the App (vue2 does not contain nvue) and H5 (vue2) side reaches 960px, the default will be calculated according to the screen width of 375px, specific configuration reference: rpx compute configuration .

The vue page supports the following common H5 units, but not in nvue:

  • rem 根字体大小可以通过 page-meta 配置抖音小程序和飞书小程序:屏幕宽度/20、百度小程序:16px、支付宝小程序:50px
  • vh viewpoint height, the height of the viewport, 1vh is equal to 1% of the height of the viewport
  • vw viewpoint width, the width of the viewport, 1vw is equal to 1% of the width of the viewport

nvue doesn't support percent units yet.

On the App side, the units involved in the titleNView in pages.json or the plus api written in the page only support px. Note that rpx is not supported at this time

In nvue, uni-app mode (Introduction to different compilation modes of nvue) can use px and rpx, the performance is basically the same as in vue, and [dynamicRpx] is also enabled ](/collocation/pages?id=globalstyle) can adapt to dynamic changes in screen size. The weex mode currently follows the unit of weex, which is special:

  • px:, a dynamically calculated length unit based on a 750-wide screen, the same concept as rpx in vue pages. (Be sure to pay attention to the px in weex mode, which is different from the px logic in vue.)
  • wx: a length unit independent of the screen width of the device, is the same concept as that of px in the vue page

The following is a detailed description of rpx:

Designers generally only provide drawing with one resolution while providing design drawing.

If you develop strictly according to the px marked by the design icon, the interface is easily deformed on mobile phones of different widths.

Width deformation is dominant. Generally, the height is not easy to go wrong on account of the scroll bar. As a result, a strong demand for dynamic width unit is triggered.

WeChat applet designed rpx to solve this problem. uni-app supports rpx on both the App side and H5 side, and can configure the calculation method of different screen widths. For details, please refer to: [rpx calculation configuration](https://uniapp.dcloud.io/collocation/pages ?id=globalstyle).

rpx is a unit relative to the reference width, which can be adapted to the screen width. uni-app The specified screen reference width is 750rpx.

Developers can calculate the rpx value of page elements based on the reference width of design draft. The conversion formula between design draft 1px and frame style 1rpx is as follows:

Design draft 1px / Design draft base width = Frame style 1rpx / 750rpx

In other words, the formula for calculating the width of the page element width in uni-app is as follows:

750 * The width of the element in the design draft / the base width of the design draft

For example:

  1. If the width of the design draft is 750px and the width of element A on the design draft is 100px, then the width of element A in uni-app should be set to: 750 * 100 / 750, the result is: 100rpx.
  2. If the width of the design draft is 640px and the width of element A on the design draft is 100px, then the width of element A in uni-app should be set to: 750 * 100 / 640, the result is: 117rpx.
  3. If the width of the design draft is 375px and the width of element B on the design draft is 200px, then the width of element B in uni-app should be set to: 750 * 200 / 375, the result is: 400rpx.

Tips

  • Note that rpx is a unit related to the width. The wider the screen, the larger the actual pixels. If you do not want to zoom according to the screen width, you should use px as the unit.
  • If the developer also uses rpx in font or height, this writing mode means that as the screen becomes wider, the font and height will become larger. If you need a fixed height, you should use px.
  • rpx does not support dynamic horizontal and vertical screen switching calculation, it is recommended to use rpx to lock the screen orientation
  • Designers can take iPhone6 as the standard of visual drafts.
  • If the design draft is not 750px, HBuilderX provides an automatic conversion tool, see: Automatically convert px to upx in HBuilderX.
  • On the App side, the units involved in the titleNView in pages.json or the plus api written in the page only support px, not rpx.
  • Early uni-app provided upx, and now it is recommended to change to rpx. See details

# style import

Use the @import statement to import the external style sheet, @import is followed by the relative path of the external style sheet to be imported, and ; indicates the end of the statement.

Sample code:

<style>
    @import "../../common/uni.css";

    .uni-card {
        box-shadow: none;
    }
</style>

# inline styles

Frame components support the use of style and class attributes to control the style of components.

  • style: static styles are uniformly written into class. style receives dynamic styles, which will be parsed at runtime. Please try to avoid writing static styles into style so as not to affect the rendering speed.
<view :style="{color:color}" />
  • class: used to specify a style rule. Its attribute value is a collection of class selector names (style class names) in the style rule. Style class names do not need to be marked with. The style class names are separated by spaces.
<view class="normal_view" />

# Selector

Currently supported selectors are:

selector sample sample description
.class .intro Select all components with class="intro"
#id #firstname Select the component with id="firstname"
element view Select all view components
element, element view, checkbox Selects all document view components and all checkbox components
::after view::after Insert content after the view component, only valid for vue pages
::before view::before Insert content before the view component, only valid for vue pages

Notice:

  • The * selector cannot be used in uni-app.

  • Only class selectors are supported in WeChat Mini Program custom components

  • page is equivalent to the body node, for example:

    <!-- 设置页面背景颜色,使用 scoped 会导致失效 -- >
      page {
    	background-color: #ccc;
    }
    

# Global and local styles

The styles defined in App.vue are global styles, which act on every page. The styles defined in the vue file in the pages directory are local styles, which only act on the corresponding pages and will cover the same selectors in App.vue.

Notice:

  • In App.vue, the external style can be imported through the @import statement, which also applies to each page.
  • nvue pages do not currently support global styles

# CSS variables

uni-app provides built-in CSS variables

CSS Variables Description App Mini Programs H5
--status-bar-height system status bar height system status bar height, nvue note below 25px 0
--window-top Distance of content area from top 0 0 Height of NavigationBar
--window-bottom Distance of content area from bottom 0 0 Height of TabBar

Notice:

  • var(--status-bar-height) This variable is a fixed 25px in the WeChat applet environment, and the actual status bar height of the mobile phone in the App.
  • When setting "navigationStyle":"custom" to cancel the native navigation bar, because the form is immersive, it occupies the position of the status bar. At this point, you can use a view with a height of var(--status-bar-height) at the top of the page to avoid the page content from appearing in the status bar.
  • Since there is no native navigation bar and tabbar on the H5 side, it is also a front-end div simulation. If a bottomed view with a fixed position is set, it will be above the tabbar on the applet and app side, but it will overlap the tabbar on the H5 side. At this point, you can use --window-bottom, whichever side is fixed above the tabbar.
  • At present, nvue does not support the --status-bar-height variable on the App side. The alternative is to obtain the status bar height through uni.getSystemInfoSync().statusBarHeight when the page is onLoad, and then use style binding to place a placeholder view sets the height. Sample code is provided below

Code block

The quick way to write css variables is: type hei in css, and you can see 3 css variables in the candidate assistant. (HBuilderX 1.9.6 and above are supported)

Example 1 - normal page using css variables:

<template>
	<!-- HBuilderX 2.6.3+ added page-meta, details: https://uniapp.dcloud.io/component/page-meta -->
	<page-meta>
		<navigation-bar />
	</page-meta>
	<view>
		<view class="status_bar">
			<!-- Here is the status bar -->
		</view>
		<view>状态栏下的文字</view>
	</view>
</template>
<style>
	.status_bar {
		height: var(--status-bar-height);
		width: 100%;
	}
</style>
<template>
	<view>
		<view class="toTop">
			<!-- An up arrow can be put here, which shifts up 10px from the bottom tabbar-->
		</view>
	</view>
</template>
<style>
	.toTop {
		bottom: calc(var(--window-bottom) + 10px);
	}
</style>

Example 2 - nvue page get status bar height

<template>
	<view class="content">
		<view :style="{ height: iStatusBarHeight + 'px'}"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				iStatusBarHeight: 0,
			};
		},
		onLoad() {
			this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight;
		},
	};
</script>

# Fixed value

The height of the following components in uni-app is fixed and cannot be modified:

Components Description App H5
NavigationBar Navigation Bar 44px 44px
TabBar Bottom Tab Before HBuilderX 2.3.4, it was 56px. From 2.3.4 onwards, it is adjusted to be consistent with H5, and unified to 50px. (but the height can be changed independently) 50px

The heights of various mini-program platforms, including iOS and Android of the same mini-program platform, are also different.

##Flex layout

In order to support cross-platform, the framework recommends using Flex layout. For Flex layout, please refer to the external document A Complete Guide to Flexbox, Ruanyifeng's flex tutorial and so on.

# Background picture

uni-app supports setting a background image in css. The usage method is basically the same as that of a normal web project, but the following points should be noted:

  • Support base64 format images.
  • Support web path images.
  • The applet does not support the use of local files in css, including local background images and font files. It needs to be used in base64 mode.
  • Note when using background images from local path:
    1. For the convenience of developers, when the background image is less than 40kb, when uni-app is compiled to a platform that does not support local background images, it will be automatically converted to base64 format;
    2. If the image is greater than or equal to 40kb, there will be performance problems. It is not recommended to use a background image that is too large. If developers must use it, they need to convert it into base64 format for use, or move it to the server and refer to it from the network address. .
    3. The reference path of the local background image is recommended to use an absolute path starting with ~@.
    .test2 {
    	background-image: url('~@/static/logo.png');
    }
    

Notice

  • Wechat applet does not support relative paths (not supported by real devices, supported by development tools)

# font icon

uni-app supports the use of font icons in the same way as normal web projects. Note the following:

  • Support base64 format font icons.
  • Support network path font icons.
  • The applet does not support the use of local files in css, including local background images and font files. It needs to be used in base64 mode.
  • The network path must add the protocol header https.
  • The code copied from http://www.iconfont.cn has no protocol header by default.
  • The font files downloaded from http://www.iconfont.cn are all fonts with the same name (the font names are all called iconfont, which can be seen when installing the font file), When using it in nvue, it should be noted that the repeated font name may display abnormally, which can be modified with tools.
  • Note when using local path icon font:
    1. For the convenience of developers, when the font file is less than 40kb, uni-app will automatically convert it to base64 format;
    2. If the font file is greater than or equal to 40kb, and it is still converted to base64, there may be performance problems. If the developer must use it, he needs to convert it into base64 format for use, or move it to the server and refer to it from the network address;
    3. It is recommended to use an absolute path starting with ~@ for the reference path of the font file.
    @font-face {
    	font-family: test1-icon;
    	src: url('~@/static/iconfont.ttf');
    }
    

In nvue, you cannot directly use css to import font files, you need to use the following methods to import font files in js. Importing fonts from local paths is not supported in nvue, please use the network link or base64 form. **The url of the src field must be enclosed in single quotes. **

var domModule = weex.requireModule('dom');
domModule.addRule('fontFace', {
	fontFamily: 'fontFamilyName',
	src: "url('https://...')",
});

Example:

<template>
	<view>
		<view>
			<text class="test">&#xe600;</text>
			<text class="test">&#xe687;</text>
			<text class="test">&#xe60b;</text>
		</view>
	</view>
</template>
<style>
	@font-face {
		font-family: 'iconfont';
		src: url('https://at.alicdn.com/t/font_865816_17gjspmmrkti.ttf') format('truetype');
	}
	.test {
		font-family: iconfont;
		margin-left: 20rpx;
	}
</style>