提交 0eddcecd 编写于 作者: D DCloud_LXH

feat: css

上级 e90b344c
# uvue css使用 # uvue css使用
uni-app x 在 app平台实现了 web css的子集。 uni-app x 在 app平台实现了 web css 的子集。
这个子集有时也被称为ucss,但工程文件仍然是css、less、scss等后缀,style节点的lang属性也没有特殊之处。 这个子集有时也被称为 ucss,但工程文件仍然是 css、less、scss 等后缀,style 节点的 lang 属性也没有特殊之处。
子集并不影响开发者开发出所需的界面,仅是写法上没有那么丰富。 子集并不影响开发者开发出所需的界面,仅是写法上没有那么丰富。
App端与web常见的区别是: 当 uni-app x 编译到 web、小程序等平台时,可以支持 web 的全部 css。同时,编译器会进行 css 重置,保证 ucss 这个子集在各端效果的一致性。
1. 仅支持flex布局
2. 选择器只能用class,不能用tag、#id、[attr]等选择器
3. 样式不继承,即父元素样式不影响子元素
但以上仅是常见的区别,并非所有,需开发者继续阅读全文。 App端与web常见的区别是:
1. 仅支持**flex 布局**
2. 选择器**只能用 class 选择器**,不能用tag、#id、[attr]等选择器
3. **样式不继承**,即父元素样式不影响子元素
当uni-app x编译到web、小程序等平台时,可以支持web的全部css。同时,编译器会进行css重置,保证ucss这个子集在各端效果的一致性 > 但以上仅是常见的区别,并非所有,需开发者继续阅读全文
## 页面布局 ## 页面布局
uni-app x 使用flex布局。这是一种清晰易用、全平台支持的布局。不管web、Android、iOS、微信skyline、快应用,均支持flex布局。 > uni-app x 使用flex布局。\
> 这是一种清晰易用、全平台支持的布局。不管web、Android、iOS、微信skyline、快应用,均支持flex布局。\
页面布局有2个注意事项,flex方向和页面级滚动 > 页面布局有2个注意事项,[flex方向](#flex-direction) 和 [页面级滚动](#pagescroll)
### flex方向 ### flex方向 @flex-direction
在web中,flex默认是横向的,但app默认是纵向的。为了多端兼容,建议开发者显式声明flex方向,不使用默认值。 在web中,flex 默认是`横向`的,但app默认是`纵向`的。为了多端兼容,建议开发者**显式声明flex方向**,不使用默认值。
```html ```html
<view style="flex-direction:row"> <view style="flex-direction:row">
...@@ -46,7 +46,7 @@ uni-app x 使用flex布局。这是一种清晰易用、全平台支持的布局 ...@@ -46,7 +46,7 @@ uni-app x 使用flex布局。这是一种清晰易用、全平台支持的布局
</style> </style>
``` ```
```html ```vue
<template> <template>
<scroll-view class="uni-column" style="flex:1"> <scroll-view class="uni-column" style="flex:1">
<view class="uni-row"> <view class="uni-row">
...@@ -63,27 +63,27 @@ uni-app x 使用flex布局。这是一种清晰易用、全平台支持的布局 ...@@ -63,27 +63,27 @@ uni-app x 使用flex布局。这是一种清晰易用、全平台支持的布局
</template> </template>
``` ```
其实flex布局概念非常简单清晰。解释下上面的代码。 ::: info 其实flex布局概念非常简单清晰。解释下上面的代码。
1. 页面根节点是一个竖排的(class="uni-column")、全屏的(style="flex:1")scroll-view,那么它的子view们就是竖排。
2. 二级view里的第一个view,设为横排,里面又放了2个三级组件text,那么这2个三级组件text是横排,即左右2个字。
想清楚页面布局,设好row还是column,界面写起来很快。 1. 页面根节点是一个纵向的(class="uni-column")、全屏的(style="flex:1")scroll-view,那么它的子view们就是纵向。
2. 二级view里的第一个view,设为横向,里面又放了2个三级组件text,那么这2个三级组件text是横向,即左右2个字。
:::
### 页面级滚动@pagescroll ### 页面级滚动@pagescroll
web开发中,页面是必然可以滚动的。当然也可以给某些div设局部滚动。 `web开发`中,页面是必然可以滚动的。当然也可以给某些div设局部滚动。
原生开发中,页面不能滚动。如果你需要某个地方滚动,那么要在相应位置放scroll-view或list-view等可滚动组件,在这些组件内部滚动。 `原生开发`中,**页面不能滚动**。如果你需要某个地方滚动,那么要在相应位置放scroll-view或list-view等可滚动组件,在这些组件内部滚动。
如果你想要整页滚动,那么可以在页面最外层套一个scroll-view,看起来就和web开发的页面滚动一样了。 如果你想要整页滚动,那么可以在页面最外层套一个scroll-view,看起来就和web开发的页面滚动一样了。
在老版nvue中,如果开发者顶层不是scroll-view,编译器会自动在外面套一层scroll-view,来变相实现页面滚动。 在老版nvue中,如果开发者顶层不是scroll-view,编译器会自动在外面套一层scroll-view,来变相实现页面滚动。\
但在uvue中,废弃了这个策略。因为开发者的页面情况较复杂,而且vue3支持多个一级组件,之前的策略可能会多给页面套一层不必要的scroll-view。 但在uvue中,废弃了这个策略。因为开发者的页面情况较复杂,而且vue3支持多个一级组件,之前的策略可能会多给页面套一层不必要的scroll-view。\
在追求高性能时,多一层scroll-view是不能忍受的。 在追求高性能时,多一层scroll-view是不能忍受的。
uvue的策略是:在新建页面时,提供一个选项,让开发者选择是否需要页面级滚动。如需要则自动在页面代码里template的根节点加一个全屏的scroll-view。 `uvue的策略`:在新建页面时,提供一个选项,让开发者选择是否需要页面级滚动。如需要则自动在页面代码里template的根节点加一个全屏的scroll-view。
如果开发者不需要,随时可以自己修改代码。
> 如果开发者不需要,随时可以自己修改代码。
```html ```html
<template> <template>
...@@ -99,17 +99,17 @@ uvue的策略是:在新建页面时,提供一个选项,让开发者选择 ...@@ -99,17 +99,17 @@ uvue的策略是:在新建页面时,提供一个选项,让开发者选择
因为web平台和基于webview的小程序使用页面滚动更方便,所以自动套在页面顶层的scroll-view写在了[条件编译](https://uniapp.dcloud.net.cn/tutorial/platform.html)里。 因为web平台和基于webview的小程序使用页面滚动更方便,所以自动套在页面顶层的scroll-view写在了[条件编译](https://uniapp.dcloud.net.cn/tutorial/platform.html)里。
> 当然如果你只做app,可以不写条件编译。
这样在web浏览器里就无需多套一层scroll-view,自然的使用浏览器的页面滚动就好了。 这样在web浏览器里就无需多套一层scroll-view,自然的使用浏览器的页面滚动就好了。
尤其在Android webview中,scroll-view其实是可区域滚动的div,滚动区变长后,性能远不如页面滚动。 尤其在Android webview中,scroll-view其实是可区域滚动的div,滚动区变长后,性能远不如页面滚动。
当然如果你只做app,可以不写条件编译。
上述代码中给scroll-view的style设为`flex:1`,意思是铺满剩余空间。设在顶层节点上,意味着铺满屏幕。 上述代码中给scroll-view的style设为`flex:1`,意思是铺满剩余空间。设在顶层节点上,意味着铺满屏幕。
当然,如果页面的pages.json里配置使用了原生导航栏,那么页面区整体是在导航栏下面。 当然,如果页面的pages.json里配置使用了原生导航栏,那么页面区整体是在导航栏下面。
- 自定义导航栏 #### 自定义导航栏
如果开发者想要自定义导航栏,首先在pages.json里对应页面的style里设置`"navigationStyle": "custom"`,关闭原生导航栏。 如果开发者想要自定义导航栏,首先在pages.json里对应页面的style里设置`"navigationStyle": "custom"`,关闭原生导航栏。
然后编写自定义的导航栏组件[\<uni-navbar-lite>](https://ext.dcloud.net.cn/plugin?id=14618),那么推荐的页面代码结构为: 然后编写自定义的导航栏组件[\<uni-navbar-lite>](https://ext.dcloud.net.cn/plugin?id=14618),那么推荐的页面代码结构为:
...@@ -130,17 +130,22 @@ uvue的策略是:在新建页面时,提供一个选项,让开发者选择 ...@@ -130,17 +130,22 @@ uvue的策略是:在新建页面时,提供一个选项,让开发者选择
> 注:这里的“原生导航栏”是一个历史沿袭叫法,指配置在pages.json里的导航栏,不属于页面代码区。事实上在uni-app x里所有界面都是原生的。 > 注:这里的“原生导航栏”是一个历史沿袭叫法,指配置在pages.json里的导航栏,不属于页面代码区。事实上在uni-app x里所有界面都是原生的。
- 页面滚动相关的生命周期、api #### 页面滚动相关的生命周期、api
在uni-app的规范中,页面滚动有一批相关的生命周期、api,比如:`onPageScroll``onReachBottom``uni.pageScrollTo()` 在uni-app的规范中,页面滚动有一批相关的生命周期、api,比如:`onPageScroll``onReachBottom``uni.pageScrollTo()`
在app端,会判断页面根节点是否为scroll-view(不认list-view等其他滚动容器)。 在app端,会判断页面根节点是否为scroll-view(不认list-view等其他滚动容器)。
* 如果是,页面滚动相关的生命周期和API继续生效,效果如前。 * 如果是,页面滚动相关的生命周期和API继续生效,效果如前。
* 如果不是scroll-view,全部失效。
> 如果根节点使用了list-view,它也有自己的滚动相关的API和监听事件。详见[list-view](../component/list-view.md)的文档。
* 如果不是scroll-view,全部失效。 ## 页面滚动引起的差异
`uni-app-x` App端无页面滚动,且其根节点高度为从导航栏底部到tabBar顶部。如果在页面根节点的子元素使用`position: absolute;`,页面内部scroll-view滚动时不会改变此元素位置。其他端有页面滚动,如果在页面根节点的子元素使用`position: absolute;`页面滚动会改变此元素的位置。如果有不随页面滚动变化位置的需求建议使用`position: fixed`
如果根节点使用了list-view,它也有自己的滚动相关的API和监听事件。详见[list-view](../component/list-view.md)的文档 注意:web端需要使用[css变量](common/variable.md)使元素不覆盖在navigationBar和tabBar上
## 样式不继承@stylenoextends ## 样式不继承@stylenoextends
...@@ -201,9 +206,17 @@ app-uvue的css的样式不继承规则,虽然与web有差异,其实只是更 ...@@ -201,9 +206,17 @@ app-uvue的css的样式不继承规则,虽然与web有差异,其实只是更
一般情况下,开发者遵循仅在text组件下写文字有关的样式,就可以编译到全端而保持界面正常。 一般情况下,开发者遵循仅在text组件下写文字有关的样式,就可以编译到全端而保持界面正常。
## 样式作用范围
`uni-app x` 中,不支持 `css scoped`,样式的作用范围遵循以下规则:
* `App.uvue` 中的样式作用于全局。
* 页面的样式作用于当前页面及其子组件。
* 组件的样式仅作用于当前组件。
## 层级 ## 层级
App仅对同层的兄弟节点之间支持z-index来调节层级。不支持脱离dom树任意调节层级。 App仅对`同层的兄弟节点`之间支持`z-index`来调节层级。不支持脱离dom树任意调节层级。
## css模块 ## css模块
...@@ -222,162 +235,10 @@ App仅对同层的兄弟节点之间支持z-index来调节层级。不支持脱 ...@@ -222,162 +235,10 @@ App仅对同层的兄弟节点之间支持z-index来调节层级。不支持脱
|CSS Variable |× | | |CSS Variable |× | |
|媒体查询 |× | | |媒体查询 |× | |
## 选择器 @selector
<!-- CSSJSON.selector_values.compatibility -->
web和小程序支持page元素选择器,以替代body元素选择器。
注意,选择器声明的变化可能会导致元素重新绘制。为了减少选择器变化引起的 DOM 更新数量,**当前只支持:CSS 声明的多个选择器中最后一个规则的变更对 DOM 的更新**
```ts
<template>
<div class="{{docBody}}">
<text class="{{rowDesc}}">描述内容</text>
</div>
</template>
<style>
.doc-body1 .row-desc1 {
color: #ff0000;
}
.doc-body1 .row-desc2 {
color: #0000ff;
}
.doc-body2 .row-desc1 {
color: #00ff00;
}
</style>
<script lang="uts">
export default {
data() {
return {
rowDesc: 'row-desc1',
docBody: 'doc-body1'
}
}
}
</script>
```
以上代码示例,当我们把 `rowDesc` 变量从 `row-desc1` 变为 `row-desc2` 时,会更新 `text` 节点样式,但是如果把 `docBody` 变量从 `doc-body1` 变为 `doc-body2`,是不会更新 `text` 节点样式的。\
因为 `doc-body` 不是最后一个选择器,非末尾的选择器变更有可能影响很多 DOM 元素,从而影响到渲染性能。
## 长度单位 @length
- 长度 `<length>` 用于表示距离尺寸的 CSS 数据类型。许多 CSS 属性会用到长度,比如 width、margin、padding。
- 长度 `<percentage>` 表述一个百分比值。许多 CSS 属性 可以取百分比值,用以根据父对象来确定大小。百分比值由一个`<number>`具体数值后跟着%符号构成。就像其他在 css 里的单位一样,在%和数值之间是不允许有空格的。
<!-- CSSJSON.length_values.compatibility -->
rpx是一个以设备750px为基准的单位,750rpx即为屏幕宽度,375rpx即为屏幕一半宽度。它比较适合适配不同宽度的手机。但rpx的性能和精度不如px,如果px可满足需求,尽量使用px。
**注意**
- 长度默认值差异
* App平台长度 `<length>` 可以不设置单位,不设置单位时当做 px 处理
* Web平台长度 `<length>` 必须设置单位,不设置单位时当做无效值处理
App平台允许设置纯数字是为了性能考虑,在需要频繁更改长度时,使用纯数字会被"数字+px"稍微快一点。\
日常开发为了更好的跨端兼容,还是推荐给长度 `<length>` 指定明确单位。
- 单位精度差异
px、rpx属于逻辑像素,在不同dpi的设备上,需要转换为物理像素。当产生浮点数时,由于精度保留策略的不同,在不同浏览器和手机OS,可能造成细微的误差。
尤其是浏览器对于小数点的px兼容不够好,比如0.5px很难正常显示。但app可以正常显示。
另外rpx和百分比,比px更容易产生浮点数,所以如果px能满足需求,尽量不用rpx和百分比。
## 颜色 @color
<!-- CSSJSON.color_values.compatibility -->
## css方法 @css-function ## css方法 @css-function
目前仅支持url()、rgb()、rgba()、var()。 目前仅支持url()、rgb()、rgba()、var()。
## CSS 变量(4.0+)@variable
uni-app x 4.0起 提供内置 CSS 变量。之前版本如有获取状态栏高度等需求可使用[uni.getWindowInfo()](../api/get-window-info.md)方式获取。
| CSS 变量| 描述| App| H5|
| :- | :- | :- | :- | :- |
| --status-bar-height | 系统状态栏高度| [系统状态栏高度](http://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.getStatusbarHeight)| 0|
| --window-top| 内容区域距离顶部的距离 | 0| NavigationBar 的高度 |
| --window-bottom| 内容区域距离底部的距离 | 0| TabBar 的高度|
**注意:**
- 当设置 `"navigationStyle":"custom"` 取消原生导航栏后,由于窗体为沉浸式,占据了状态栏位置。此时可以使用一个高度为 `var(--status-bar-height)` 的 view 放在页面顶部,避免页面内容出现在状态栏。
- 在 Web 端,由于不存在原生导航栏和 tabBar(是前端 div 模拟的),如果设置了一个固定位置的居底 view,在小程序和 App 端是在 tabBar 上方,但在 H5 端会与 tabBar 重叠。此时可使用`--window-bottom`,不管在哪个端,都是固定在 tabBar 上方。
**代码块**
快速书写 css 变量的方法是:在 css 中敲 hei,在候选助手中即可看到 3 个 css 变量。
示例:
```html
<template>
<view>
<view class="status_bar">
<!-- 这里是状态栏 -->
</view>
<view>状态栏下的文字</view>
</view>
</template>
<style>
.status_bar {
height: var(--status-bar-height);
width: 100%;
}
</style>
```
```html
<template>
<view>
<view class="toTop">
<!-- 这里可以放一个向上箭头,它距离底部tabBar上浮10px-->
</view>
</view>
</template>
<style>
.toTop {
bottom: calc(var(--window-bottom) + 10px);
}
</style>
```
## At-rules
<!-- CSSJSON.at_rules_values.compatibility -->
@font-face自定义字体示例:
```html
<style>
@font-face {
font-family: AlimamaDaoLiTiOTF;
src: url('/static/font/AlimamaDaoLiTi.otf');
}
</style>
```
Tips:
- 字体路径支持网络和本地,本地字体请注意放在项目或uni_modules的static目录下。
## 样式作用范围
`uni-app x` 中,不支持 `css scoped`,样式的作用范围遵循以下规则:
* `App.uvue` 中的样式作用于全局。
* 页面的样式作用于当前页面及其子组件。
* 组件的样式仅作用于当前组件。
## 页面滚动引起的差异
`uni-app-x` App端无页面滚动,且其根节点高度为从导航栏底部到tabBar顶部。如果在页面根节点的子元素使用`position: absolute;`,页面内部scroll-view滚动时不会改变此元素位置。其他端有页面滚动,如果在页面根节点的子元素使用`position: absolute;`页面滚动会改变此元素的位置。如果有不随页面滚动变化位置的需求建议使用`position: fixed`。注意web端需要使用[css变量](#variable)使元素不覆盖在navigationBar和tabBar上。
<!-- CSSJSON.readmeTable.name --> <!-- CSSJSON.readmeTable.name -->
<!-- CSSJSON.readmeTable.compatibility --> <!-- CSSJSON.readmeTable.compatibility -->
......
* [CSS概述](README.md) * [CSS 概述](README.md)
* [align-content](align-content.md) * [选择器](common/selector.md)
* [align-items](align-items.md) * [长度单位](common/length.md)
* [background](background.md) * [颜色](common/color.md)
* [background-clip](background-clip.md) * [At-rules](common/at-rules.md)
* [background-color](background-color.md) * [CSS 变量](common/variable.md)
* [background-image](background-image.md) * CSS 属性```{"collapsable": false}```
* [border](border.md) * [align-content](align-content.md)
* [border-bottom-color](border-bottom-color.md) * [align-items](align-items.md)
* [border-bottom-left-radius](border-bottom-left-radius.md) * [background](background.md)
* [border-bottom-right-radius](border-bottom-right-radius.md) * [background-clip](background-clip.md)
* [border-bottom-style](border-bottom-style.md) * [background-color](background-color.md)
* [border-bottom-width](border-bottom-width.md) * [background-image](background-image.md)
* [border-color](border-color.md) * [border](border.md)
* [border-left-color](border-left-color.md) * [border-bottom-color](border-bottom-color.md)
* [border-left-style](border-left-style.md) * [border-bottom-left-radius](border-bottom-left-radius.md)
* [border-left-width](border-left-width.md) * [border-bottom-right-radius](border-bottom-right-radius.md)
* [border-radius](border-radius.md) * [border-bottom-style](border-bottom-style.md)
* [border-right-color](border-right-color.md) * [border-bottom-width](border-bottom-width.md)
* [border-right-style](border-right-style.md) * [border-color](border-color.md)
* [border-right-width](border-right-width.md) * [border-left-color](border-left-color.md)
* [border-style](border-style.md) * [border-left-style](border-left-style.md)
* [border-top-color](border-top-color.md) * [border-left-width](border-left-width.md)
* [border-top-left-radius](border-top-left-radius.md) * [border-radius](border-radius.md)
* [border-top-right-radius](border-top-right-radius.md) * [border-right-color](border-right-color.md)
* [border-top-style](border-top-style.md) * [border-right-style](border-right-style.md)
* [border-top-width](border-top-width.md) * [border-right-width](border-right-width.md)
* [border-width](border-width.md) * [border-style](border-style.md)
* [bottom](bottom.md) * [border-top-color](border-top-color.md)
* [box-shadow](box-shadow.md) * [border-top-left-radius](border-top-left-radius.md)
* [box-sizing](box-sizing.md) * [border-top-right-radius](border-top-right-radius.md)
* [color](color.md) * [border-top-style](border-top-style.md)
* [display](display.md) * [border-top-width](border-top-width.md)
* [flex](flex.md) * [border-width](border-width.md)
* [flex-basis](flex-basis.md) * [bottom](bottom.md)
* [flex-direction](flex-direction.md) * [box-shadow](box-shadow.md)
* [flex-flow](flex-flow.md) * [box-sizing](box-sizing.md)
* [flex-grow](flex-grow.md) * [color](color.md)
* [flex-shrink](flex-shrink.md) * [display](display.md)
* [flex-wrap](flex-wrap.md) * [flex](flex.md)
* [font-family](font-family.md) * [flex-basis](flex-basis.md)
* [font-size](font-size.md) * [flex-direction](flex-direction.md)
* [font-style](font-style.md) * [flex-flow](flex-flow.md)
* [font-weight](font-weight.md) * [flex-grow](flex-grow.md)
* [height](height.md) * [flex-shrink](flex-shrink.md)
* [justify-content](justify-content.md) * [flex-wrap](flex-wrap.md)
* [left](left.md) * [font-family](font-family.md)
* [line-height](line-height.md) * [font-size](font-size.md)
* [margin](margin.md) * [font-style](font-style.md)
* [margin-bottom](margin-bottom.md) * [font-weight](font-weight.md)
* [margin-left](margin-left.md) * [height](height.md)
* [margin-right](margin-right.md) * [justify-content](justify-content.md)
* [margin-top](margin-top.md) * [left](left.md)
* [max-height](max-height.md) * [line-height](line-height.md)
* [max-width](max-width.md) * [margin](margin.md)
* [min-height](min-height.md) * [margin-bottom](margin-bottom.md)
* [min-width](min-width.md) * [margin-left](margin-left.md)
* [opacity](opacity.md) * [margin-right](margin-right.md)
* [overflow](overflow.md) * [margin-top](margin-top.md)
* [padding](padding.md) * [max-height](max-height.md)
* [padding-bottom](padding-bottom.md) * [max-width](max-width.md)
* [padding-left](padding-left.md) * [min-height](min-height.md)
* [padding-right](padding-right.md) * [min-width](min-width.md)
* [padding-top](padding-top.md) * [opacity](opacity.md)
* [position](position.md) * [overflow](overflow.md)
* [right](right.md) * [padding](padding.md)
* [text-align](text-align.md) * [padding-bottom](padding-bottom.md)
* [text-decoration](text-decoration.md) * [padding-left](padding-left.md)
* [text-decoration-color](text-decoration-color.md) * [padding-right](padding-right.md)
* [text-decoration-line](text-decoration-line.md) * [padding-top](padding-top.md)
* [text-decoration-style](text-decoration-style.md) * [position](position.md)
* [text-overflow](text-overflow.md) * [right](right.md)
* [text-decoration-thickness](text-decoration-thickness.md) * [text-align](text-align.md)
* [top](top.md) * [text-decoration](text-decoration.md)
* [transform](transform.md) * [text-decoration-color](text-decoration-color.md)
* [transform-origin](transform-origin.md) * [text-decoration-line](text-decoration-line.md)
* [transition](transition.md) * [text-decoration-style](text-decoration-style.md)
* [transition-delay](transition-delay.md) * [text-overflow](text-overflow.md)
* [transition-duration](transition-duration.md) * [text-decoration-thickness](text-decoration-thickness.md)
* [transition-property](transition-property.md) * [top](top.md)
* [transition-timing-function](transition-timing-function.md) * [transform](transform.md)
* [width](width.md) * [transform-origin](transform-origin.md)
* [z-index](z-index.md) * [transition](transition.md)
* [visibility](visibility.md) * [transition-delay](transition-delay.md)
* [lines](lines.md) * [transition-duration](transition-duration.md)
* [align-self](align-self.md) * [transition-property](transition-property.md)
* [pointer-events](pointer-events.md) * [transition-timing-function](transition-timing-function.md)
\ No newline at end of file * [width](width.md)
* [z-index](z-index.md)
* [visibility](visibility.md)
* [lines](lines.md)
* [align-self](align-self.md)
* [pointer-events](pointer-events.md)
\ No newline at end of file
# At-rules
<!-- CSSJSON.at_rules_values.compatibility -->
@font-face自定义字体示例:
```html
<style>
@font-face {
font-family: AlimamaDaoLiTiOTF;
src: url('/static/font/AlimamaDaoLiTi.otf');
}
</style>
```
\ No newline at end of file
# 颜色 @color
<!-- CSSJSON.color_values.compatibility -->
\ No newline at end of file
# 长度单位 @length
- 长度 `<length>` 用于表示距离尺寸的 CSS 数据类型。许多 CSS 属性会用到长度,比如 width、margin、padding。
- 长度 `<percentage>` 表述一个百分比值。许多 CSS 属性 可以取百分比值,用以根据父对象来确定大小。百分比值由一个`<number>`具体数值后跟着%符号构成。就像其他在 css 里的单位一样,在%和数值之间是不允许有空格的。
- `rpx` 是一个以设备750px为基准的单位,750rpx即为屏幕宽度,375rpx即为屏幕一半宽度。它比较适合适配不同宽度的手机。但rpx的性能和精度不如px,**如果px可满足需求,尽量使用px**
<!-- CSSJSON.length_values.compatibility -->
::: warning 注意
- 长度默认值差异
* App平台长度 `<length>` 可以不设置单位,不设置单位时当做 px 处理
* Web平台长度 `<length>` 必须设置单位,不设置单位时当做无效值处理 \
App平台允许设置纯数字是为了性能考虑,在需要频繁更改长度时,使用纯数字会被"数字+px"稍微快一点。\
日常开发为了更好的跨端兼容,还是推荐给长度 `<length>` 指定明确单位。
- 单位精度差异
- px、rpx属于逻辑像素,在不同dpi的设备上,需要转换为物理像素。当产生浮点数时,由于精度保留策略的不同,在不同浏览器和手机OS,可能造成细微的误差。\
尤其是浏览器对于小数点的px兼容不够好,比如`0.5px`很难正常显示。但app可以正常显示。\
另外`rpx``百分比`,比`px`更容易产生浮点数,所以**如果px能满足需求,尽量不用rpx和百分比**
:::
# 选择器 @selector
> web和小程序支持page元素选择器,以替代body元素选择器。
<!-- CSSJSON.selector_values.compatibility -->
::: warning 注意
选择器声明的变化可能会导致元素重新绘制。为了减少选择器变化引起的 DOM 更新数量,**当前只支持:CSS 声明的多个选择器中最后一个规则的变更对 DOM 的更新**
:::
## 示例
```vue
<template>
<div :class="{{docBody}}">
<text :class="{{rowDesc}}">描述内容</text>
</div>
</template>
<style>
.doc-body1 .row-desc1 {
color: #ff0000;
}
.doc-body1 .row-desc2 {
color: #0000ff;
}
.doc-body2 .row-desc1 {
color: #00ff00;
}
</style>
<script lang="uts">
export default {
data() {
return {
rowDesc: 'row-desc1',
docBody: 'doc-body1'
}
}
}
</script>
```
以上代码示例,当我们把 `rowDesc` 变量从 `row-desc1` 变为 `row-desc2` 时,会更新 `text` 节点样式,但是如果把 `docBody` 变量从 `doc-body1` 变为 `doc-body2`,是不会更新 `text` 节点样式的。\
因为 `doc-body` 不是最后一个选择器,非末尾的选择器变更有可能影响很多 DOM 元素,从而影响到渲染性能。
# CSS 变量 <Badge text="4.0">
> uni-app x 4.0起 提供内置 CSS 变量。之前版本如有获取状态栏高度等需求可使用[uni.getWindowInfo()](../api/get-window-info.md)方式获取。
| CSS 变量| 描述| App| web|
| :- | :- | :- | :- | :- |
| --status-bar-height | 系统状态栏高度| [系统状态栏高度](http://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.getStatusbarHeight)| 0|
| --window-top| 内容区域距离顶部的距离 | 0| NavigationBar 的高度 |
| --window-bottom| 内容区域距离底部的距离 | 0| TabBar 的高度|
::: warning 注意
- 当设置 `"navigationStyle":"custom"` 取消原生导航栏后,由于窗体为沉浸式,占据了状态栏位置。此时可以使用一个高度为 `var(--status-bar-height)` 的 view 放在页面顶部,避免页面内容出现在状态栏。
- 在 Web 端,由于不存在原生导航栏和 tabBar(是前端 div 模拟的),如果设置了一个固定位置的居底 view,在小程序和 App 端是在 tabBar 上方,但在 H5 端会与 tabBar 重叠。此时可使用`--window-bottom`,不管在哪个端,都是固定在 tabBar 上方。
:::
## 代码块
快速书写 css 变量的方法是:在 css 中敲 `hei`,在候选助手中即可看到 3 个 css 变量。
## 示例
```vue
<template>
<view>
<view class="status_bar">
<!-- 这里是状态栏 -->
</view>
<view>状态栏下的文字</view>
</view>
</template>
<style>
.status_bar {
height: var(--status-bar-height);
width: 100%;
}
</style>
```
```vue
<template>
<view>
<view class="toTop">
<!-- 这里可以放一个向上箭头,它距离底部tabBar上浮10px-->
</view>
</view>
</template>
<style>
.toTop {
bottom: calc(var(--window-bottom) + 10px);
}
</style>
```
## Tips
- `字体路径`支持**网络****本地**,本地字体请注意放在项目或uni_modules的static目录下。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册