页面样式与布局

尺寸单位

uni-app 支持的通用 css 单位包括 px、rpx

  • px 即屏幕像素
  • rpx 即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大,但在 App 端和 H5 端屏幕宽度达到 960px 时,默认将按照 375px 的屏幕宽度进行计算,具体配置参考:rpx计算配置

vue页面支持普通H5单位,但在nvue里不支持:

  • rem 根字体大小可以通过 page-meta 配置 ?????????????
  • vh viewpoint height,视窗高度,1vh等于视窗高度的1%
  • vw viewpoint width,视窗宽度,1vw等于视窗宽度的1%

nvue还不支持百分比单位。

App端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px。注意此时不支持 rpx
**
nvue中,uni-app 模式(nvue 不同编译模式介绍)可以使用 px 、rpx,表现与 vue 中一致。

weex 模式目前遵循weex的单位,它的单位比较特殊:

  • px:,以750宽的屏幕为基准动态计算的长度单位,与 vue 页面中的 rpx 理念相同。

(一定要注意 weex 模式的 px,和 vue 里的 px 逻辑不一样。)

  • wx:与设备屏幕宽度无关的长度单位,与 vue 页面中的 px 理念相同

下面对 rpx 详细说明:

设计师在提供设计图时,一般只提供一个分辨率的图。
严格按设计图标注的 px 做开发,在不同宽度的手机上界面很容易变形。
而且主要是宽度变形。高度一般因为有滚动条,不容易出问题。由此,引发了较强的动态宽度单位需求。

微信小程序设计了 rpx 解决这个问题。
uni-app 在 App 端、H5 端都支持了 rpx,并且可以配置不同屏幕宽度的计算方式,具体参考:rpx计算配置

rpx 是相对于基准宽度的单位,可以根据屏幕宽度进行自适应。
uni-app 规定屏幕基准宽度 750rpx。
开发者可以通过设计稿基准宽度计算页面元素 rpx 值,设计稿 1px 与框架样式 1rpx 转换公式如下:
设计稿 1px / 设计稿基准宽度 = 框架样式 1rpx / 750rpx
换言之,页面元素宽度在 uni-app 中的宽度计算公式:
750 * 元素在设计稿中的宽度 / 设计稿基准宽度
举例说明:

  1. 若设计稿宽度为 750px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 750,结果为:100rpx。
  2. 若设计稿宽度为 640px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 640,结果为:117rpx。
  3. 若设计稿宽度为 375px,元素 B 在设计稿上的宽度为 200px,那么元素 B 在 uni-app 里面的宽度应该设为:750 * 200 / 375,结果为:400rpx。

Tips

  • 注意 rpx 是和宽度相关的单位,屏幕越宽,该值实际像素越大。如不想根据屏幕宽度缩放,则应该使用 px 单位。
  • 如果开发者在字体或高度中也使用了 rpx ,那么需注意这样的写法意味着随着屏幕变宽,字体会变大、高度会变大。如果你需要固定高度,则应该使用 px 。
  • rpx不支持动态横竖屏切换计算,使用rpx建议锁定屏幕方向
  • 设计师可以用 iPhone6 作为视觉稿的标准。
  • 如果设计稿不是750px,HBuilderX提供了自动换算的工具,详见:https://ask.dcloud.net.cn/article/35445
  • App端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px,不支持 rpx。
  • 早期 uni-app 提供了 upx ,目前已经推荐统一改为 rpx 了详见

样式导入

使用@import语句可以导入外联样式表,
@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。
示例代码:

  1. <style>
  2. @import "../../common/uni.css";
  3. .uni-card {
  4. box-shadow: none;
  5. }
  6. </style>

内联样式

框架组件上支持使用 style、class 属性来控制组件的样式。

  • style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。

    1. <view :style="{color:color}" />
  • class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。

    1. <view class="normal_view" />

选择器

目前支持的选择器有:

选择器 样例 样例描述
.class .intro 选择所有拥有 class=”intro” 的组件
#id #firstname 选择拥有 id=”firstname” 的组件
element view 选择所有 view 组件
element, element view, checkbox 选择所有文档的 view 组件和所有的 checkbox 组件
::after view::after 在 view 组件后边插入内容,仅微信小程序和App生效
::before view::before 在 view 组件前边插入内容,仅微信小程序和App生效

注意:

  • uni-app 中不能使用 * 选择器。
  • page 相当于 body 节点,例如:
  • 微信小程序自定义组件中仅支持 class 选择器
    1. <!-- 设置页面背景颜色 -->
    2. page {
    3. background-color:#ccc;
    4. }

全局样式与局部样式

定义在 App.vue 中的样式为全局样式,作用于每一个页面。
在 pages 目录下 的 vue 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 App.vue 中相同的选择器。
注意:

  • App.vue 中通过 @import 语句可以导入外联样式,一样作用于每一个页面。
  • nvue页面暂不支持全局样式

CSS变量

uni-app 提供内置 CSS 变量

CSS变量 描述 App 小程序 H5
—status-bar-height 系统状态栏高度 系统状态栏高度、nvue注意见下 25px 0
—window-top 内容区域距离顶部的距离 0 0 NavigationBar 的高度
—window-bottom 内容区域距离底部的距离 0 0 TabBar 的高度

注意:

  • var(--status-bar-height) 此变量在微信小程序环境为固定 25px,在 App 里为手机实际状态栏高度。
  • 当设置 "navigationStyle":"custom" 取消原生导航栏后,由于窗体为沉浸式,占据了状态栏位置。此时可以使用一个高度为 var(--status-bar-height) 的 view 放在页面顶部,避免页面内容出现在状态栏。
  • 由于在H5端,不存在原生导航栏和tabbar,也是前端div模拟。如果设置了一个固定位置的居底view,在小程序和App端是在tabbar上方,但在H5端会与tabbar重叠。此时可使用--window-bottom,不管在哪个端,都是固定在tabbar上方。
  • 目前 nvue 在App端,还不支持 --status-bar-height变量,替代方案是在页面onLoad时通过uni.getSystemInfoSync().statusBarHeight获取状态栏高度,然后通过style绑定方式给占位view设定高度。下方提供了示例代码
  • 我的华为手机,利用height: calc(var(**--status-bar-height) + 2.25rem),高度有点不一致,后来改用了API去获取status-bar-height,放在padding-top里面,高度才一致**

image.png
代码块
快速书写css变量的方法是:在css中敲hei,在候选助手中即可看到3个css变量。(HBuilderX 1.9.6以上支持)
示例1 - 普通页面使用css变量:

  1. <template>
  2. <!-- HBuilderX 2.6.3+ 新增 page-meta, 详情:https://uniapp.dcloud.io/component/page-meta -->
  3. <page-meta>
  4. <navigation-bar />
  5. </page-meta>
  6. <view>
  7. <view class="status_bar">
  8. <!-- 这里是状态栏 -->
  9. </view>
  10. <view> 状态栏下的文字 </view>
  11. </view>
  12. </template>
  13. <style>
  14. .status_bar {
  15. height: var(--status-bar-height);
  16. width: 100%;
  17. }
  18. </style>
  1. <template>
  2. <view>
  3. <view class="toTop">
  4. <!-- 这里可以放一个向上箭头,它距离底部tabbar上浮10px-->
  5. </view>
  6. </view>
  7. </template>
  8. <style>
  9. .toTop {
  10. bottom: calc(var(--window-bottom) + 10px)
  11. }
  12. </style>

示例2 - nvue页面获取状态栏高度

  1. <template>
  2. <view class="content">
  3. <view :style="{ height: iStatusBarHeight + 'px'}"></view>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. data() {
  9. return {
  10. iStatusBarHeight:0
  11. }
  12. },
  13. onLoad() {
  14. this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight
  15. }
  16. }
  17. </script>

固定值

uni-app 中以下组件的高度是固定的,不可修改:

组件 描述 App H5
NavigationBar 导航栏 44px 44px
TabBar 底部选项卡 HBuilderX 2.3.4之前为56px,2.3.4起和H5调为一致,统一为 50px。但可以自主更改高度) 50px

各小程序平台,包括同小程序平台的iOS和Android的高度也不一样。


Flex布局

为支持跨平台,框架建议使用Flex布局,关于Flex布局可以参考外部文档A Complete Guide to Flexbox阮一峰的flex教程等。


背景图片

uni-app 支持使用在 css 里设置背景图片,使用方式与普通 web 项目大体相同,但需要注意以下几点:

  • 支持 base64 格式图片。
  • 支持网络路径图片。
  • 小程序不支持在css中使用本地文件**,包括本地的背景图和字体文件**。需以base64方式方可使用。

    1. App端在v3模式以前,也有相同限制。v3编译模式起支持直接使用本地背景图和字体。
  • 使用本地路径背景图片需注意:

    1. 为方便开发者,在背景图片小于 40kb 时,uni-app 编译到不支持本地背景图的平台时,会自动将其转化为 base64 格式;
    2. 图片大于等于 40kb,会有性能问题,不建议使用太大的背景图,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用。
    3. 本地背景图片的引用路径推荐使用以 ~@ 开头的绝对路径。
      1. .test2 {
      2. background-image: url('~@/static/logo.png');
      3. }
      注意
  • 微信小程序不支持相对路径(真机不支持,开发工具支持)


字体图标

uni-app 支持使用字体图标,使用方式与普通 web 项目相同,需要注意以下几点:

  • 支持 base64 格式字体图标。
  • 支持网络路径字体图标。
  • 小程序不支持在css中使用本地文件,包括本地的背景图和字体文件。需以base64方式方可使用。App端在v3模式以前,也有相同限制。v3编译模式起支持直接使用本地背景图和字体。
  • 网络路径必须加协议头 https
  • http://www.iconfont.cn 上拷贝的代码,默认是没加协议头的。
  • http://www.iconfont.cn 上下载的字体文件,都是同名字体(字体名都叫iconfont,安装字体文件时可以看到),在nvue内使用时需要注意,此字体名重复可能会显示不正常,可以使用工具修改。
  • 使用本地路径图标字体需注意:
    1. 为方便开发者,在字体文件小于 40kb 时,uni-app 会自动将其转化为 base64 格式;
    2. 字体文件大于等于 40kb,仍转换为 base64 方式使用的话可能有性能问题,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用;
    3. 字体文件的引用路径推荐使用以 ~@ 开头的绝对路径。
      1. @font-face {
      2. font-family: test1-icon;
      3. src: url('~@/static/iconfont.ttf');
      4. }
      nvue中不可直接使用css的方式引入字体文件,需要使用以下方式在js内引入。nvue内不支持本地路径引入字体,请使用网络链接或者base64形式。src字段的url的括号内一定要使用单引号。
      1. var domModule = weex.requireModule('dom');
      2. domModule.addRule('fontFace', {
      3. 'fontFamily': "fontFamilyName",
      4. 'src': "url('https://...')"
      5. })
      示例:
      1. <template>
      2. <view>
      3. <view>
      4. <text class="test">&#xe600;</text>
      5. <text class="test">&#xe687;</text>
      6. <text class="test">&#xe60b;</text>
      7. </view>
      8. </view>
      9. </template>
      10. <style>
      11. @font-face {
      12. font-family: 'iconfont';
      13. src: url('https://at.alicdn.com/t/font_865816_17gjspmmrkti.ttf') format('truetype');
      14. }
      15. .test {
      16. font-family: iconfont;
      17. margin-left: 20rpx;
      18. }
      19. </style>

资料:如何引用字体图标

/ 微信小程序中引用FontAwesome字体 https://blog.csdn.net/qq_28988969/article/details/76633921 /

1.到Font Awesome官网下载字体包

官网链接:Font Awesome中文官网

2.打开1中下载的压缩包找到.ttf文件

如下图所示:
7.页面样式与布局 - 图2

3.上传2中的字体文件到https://transfonter.org/,选择base64 编吗 ,convert后下载

如下图所示:
7.页面样式与布局 - 图3
下一步
7.页面样式与布局 - 图4

4.打开3中下载的文件,找到stylesheet.css

7.页面样式与布局 - 图5

5.在桌面新建一个fontAwesome.wxss文件

7.页面样式与布局 - 图6

6.打开4中的文件,复制里面的代码到5中的新建的fontAwesome.wxss文件中

stylesheet.css代码如下:
7.页面样式与布局 - 图7
复制到fontAwesome.wxss中:
7.页面样式与布局 - 图8

7.打开1中的文件font-awesome.css,复制里面的css(去掉@font-face部分)到新建的fontAwesome.wxss文件中(接着6中复制内容的后面)

font-awesome.css如下:
7.页面样式与布局 - 图9
打开文件:
7.页面样式与布局 - 图10
复制其余部分到fontAwesome.wxss
7.页面样式与布局 - 图11

8.然后引入小程序中直接用就可以了

  1. <view class="weui-cells weui-cells_after-title bug">
  2. <navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">
  3. <view class="weui-cell__hd">
  4. <icon class="fa fa-bug fa-lg" />
  5. </view>
  6. <view class="weui-cell__bd">建议反馈</view>
  7. <view class="weui-cell__ft weui-cell__ft_in-access"></view>
  8. </navigator>
  9. </view>