FlexUI Engine(FlexView)CSS 支持范围
适用范围:
flexui-engine原生渲染路径(OHOS / Android 上的 FlexView 卡片)。 本文档基于当前ai分支代码梳理,列出实际实现的 CSS 支持与不支持清单,而非上游 Hippy 的参考文档。 最后核对:2026-08(driver/js/packages/flexui-backend、toolkit/flexui-stylesheet-compiler、flexui-engine/dom、framework/ohos/src/main/cpp)。效果专项(透明度蒙层 / 渐变 / 模糊的代码级核查与开发投入)见
docs/design/flexui-engine-effects-capability.md。
1. 渲染链路与样式优先级
样式从 WXSS 到原生控件经过 4 个环节:
WXSS
└─ flexui-stylesheet-compiler (Rust/cssparser, 编译期)
· 类名前缀(样式隔离) · rpx → vw · :host 转换 · @import 内联 · @media 保留为 MediaRule
└─ flexui-webpack-plugin css-rulejson-loader (构建期, 手写简易解析器)
· CSS 文本 → RulesJSON:{ hash, selectors[], declarations[] } / { type:'media', media, rules[] }
└─ CSSManager (运行时, flexui-backend)
· 按 id / class / type / universal 建索引;scoped class 经 bindPathScope 绑定组件作用域
· @media 直接跳过(Phase 2 未实现)
└─ StyleResolver (运行时)
· 4 层样式合并 + 简写展开 + 单位/颜色转换 → 序列化给 C++ DOM → Taitank/Yoga 布局 → ArkUI/View 渲染
样式合并优先级(低 → 高),StyleResolver.resolve():
defaultNativeStyle—— 组件适配器默认样式(见 §8)- 继承样式 —— 父级文字属性(见 §6)
- CSS 匹配 ——
CSSManager.query()结果(特异性排序,见 §7) - inline style ——
setStyle()/ style 属性(最高)
重要:两级支持 ≠ 两级生效。 CSS 属性先经 JS 侧
PROPERTIES_MAP做 kebab→camelCase 映射(§2), 再经 C++ 渲染端按键消费(FRNodeProps/ 各组件SetProp,见 §2 各表"生效"列)。 映射存在 ≠ 生效:box-shadow、text-shadow、text-decoration等映射目标与 C++ 消费键不一致, CSS 简写实际不生效(需用 camelCase 分键,见 §2.4 / §9.1)。
2. 支持的 CSS 属性(完整列表)
属性名映射表定义于 flexui-backend/src/native-backend/StyleResolver.ts 的 PROPERTIES_MAP
(kebab-case CSS 名 → camelCase 原生属性名)。生效列表示该键被 C++ 渲染端消费
(dom/node_props.h 布局键 或 framework/ohos/.../fr_node_props.h 视图键,经 base_view.cc / rich_text_view.cc 等消费)。
2.1 布局与盒模型(Taitank/Yoga 布局层消费)
| CSS 属性 | 目标键 | 生效 | 说明 |
|---|---|---|---|
display |
display | ✅ | 仅 none / inline / inline-block / block / flex 有效,其他值静默丢弃 |
width / height |
width / height | ✅ | 数字、px、rpx、%、vw/vh、auto |
min-width / max-width / min-height / max-height |
minWidth 等 | ⚠️ | 无 kebab 映射;CSS 写 kebab 形式不生效,需 camelCase(minWidth)或内联 |
flex-direction |
flexDirection | ✅ | display:flex 且未显式设置时默认 row(对齐 W3C,纠正 Yoga 默认 column) |
flex-wrap |
flexWrap | ✅ | |
flex-grow / flex-shrink / flex-basis |
同名 | ✅ | flex 简写可展开(见 §3) |
align-items / align-self / align-content |
同名 | ✅ | normal 自动归一为 stretch;百分比尺寸子元素在父 align-items 非 stretch 时自动补 alignSelf:stretch |
justify-content |
justifyContent | ✅ | |
margin-top/right/bottom/left |
marginTop/Right/Bottom/Left | ✅ | margin 简写支持 1-4 值(见 §3);另有 marginVertical/Horizontal 键 |
padding-top/right/bottom/left |
paddingTop/Right/Bottom/Left | ✅ | 同上 |
position |
position | ✅ | Yoga 语义:absolute / relative;不支持 fixed/sticky |
top / right / bottom / left |
同名 | ✅ | 配合 position: absolute |
z-index |
zIndex | ✅ | |
overflow |
overflow | ✅ | visible / hidden(C++ 转 clip 开关) |
overflow-x / overflow-y |
overflowX / overflowY | ❌ | C++ 只认 overflow 键 |
aspect-ratio |
aspectRatio | ⚠️ | 无 kebab 映射,camelCase 透传;C++ 布局层有该键 |
box-sizing |
box-sizing | ✅ | border-box:声明宽/高含 padding+border,布局前换算内容尺寸(内容 = 声明 − padding − border);% 子元素按父 content 宽 解析。默认 content-box(2026-08 修复:原恒 content-box 导致 width:100% + padding 超窗,见 taitank_layout_node.cc) |
float / clear |
— | ❌ | Yoga 无浮动布局 |
inset / inset-* |
— | ❌ | 只认 top/right/bottom/left |
2.2 背景
| CSS 属性 | 目标键 | 生效 | 说明 |
|---|---|---|---|
background-color |
backgroundColor | ✅ | 颜色见 §5 |
background-image |
backgroundImage | ✅ | SetBackgroundImage(url) |
background-size |
backgroundSize | ✅ | 转 ArkUI ImageSize |
background-position-x / background-position-y |
同名 | ✅ | 分键形式 |
background-position |
backgroundPosition | ❌ | C++ 只认 position-x/y 分键 |
background-repeat |
backgroundRepeat | ❌ | 渲染端无消费 |
background-origin / background-clip |
同名 | ❌ | 渲染端无消费 |
background(简写) |
backgroundColor / linearGradient | ✅ | 仅纯色与 linear-gradient(...) 两种(见 §3);渐变支持无角度(默认 180°)、命名方向、turn/rad/grad、transparent/命名色/8 位 hex 色标,由 JS 归一化为 CSS 度数(见效果专项文档 §2.2) |
2.3 边框与圆角
| CSS 属性 | 目标键 | 生效 | 说明 |
|---|---|---|---|
border-width / 各方向 -top/-right/-bottom/-left-width |
同名 | ✅ | |
border-color / 各方向 -color |
同名 | ✅ | |
border-style / 各方向 -style |
同名 | ✅ | solid / dashed / dotted / none |
border(简写) |
borderWidth/Style/Color | ✅ | 见 §3 |
border-radius |
borderRadius | ✅ | 1-4 值简写展开;百分比圆角在 JS 侧解析(宽高已知精确计算,否则 9999 让 ArkUI 裁成圆/胶囊) |
border-top-left-radius / -top-right- / -bottom-left- / -bottom-right- |
同名 | ✅ |
2.4 阴影(⚠️ CSS 简写不生效,仅分键生效)
| CSS 属性 | 目标键 | 生效 | 说明 |
|---|---|---|---|
box-shadow(简写) |
boxShadow | ❌ | 不生效:C++ 只按分键消费,JS 侧不拆分简写字符串 |
text-shadow(简写) |
textShadow | ❌ | 不生效:同上,C++ 只认 textShadowOffset/Color/Radius |
| — | shadowColor / shadowOffset(X/Y) / shadowOpacity / shadowRadius | ✅ | 生效:需以 camelCase 键传入(inline style / setStyle);shadowSpread 键存在但 OHOS 不支持(// ohos not support) |
| — | textShadowColor / textShadowOffset / textShadowRadius | ✅ | 生效:camelCase 键;textShadowOffset 传 {width,height} 对象(或由 textShadowOffsetX/Y 合并) |
2.5 文本
| CSS 属性 | 目标键 | 生效 | 说明 |
|---|---|---|---|
color |
color | ✅ | 默认黑 0xFF000000(Text/Span/Input/Textarea) |
font-size |
fontSize | ✅ | |
font-weight / font-style / font-family |
同名 | ✅ | |
line-height |
lineHeight | ✅ | 无单位数字按 CSS 2.1 视为倍数:相对自身 font-size 解析,以倍数继承(_lineHeightUnitless),子元素按自身 font-size 重算 |
text-align |
textAlign | ✅ | 可通过 View 继承传给子 Text |
text-decoration(简写) |
textDecoration | ❌ | 不生效:C++ 只认 textDecorationLine / textDecorationColor / textDecorationStyle 分键 |
letter-spacing |
letterSpacing | ✅ | |
vertical-align |
verticalAlign | ✅ | 渲染端有该键 |
word-spacing |
wordSpacing | ❌ | 渲染端无消费 |
white-space |
whiteSpace | ❌ | 渲染端无消费 |
word-break |
wordBreak | ❌ | C++ 认 breakStrategy(camelCase 透传可生效,CSS 简写不生效) |
text-indent |
textIndent | ❌ | 渲染端无消费 |
text-overflow |
textOverflow | ❌ | C++ 认 textOverflowMode(Text 组件经 overflow 属性 / attributeMaps 映射) |
-wx-line-clamp |
lineClamp | ❌ | C++ 认 numberOfLines(Text 组件用 max-lines / maxLines 属性) |
2.6 变换与视觉效果
| CSS 属性 | 目标键 | 生效 | 说明 |
|---|---|---|---|
transform |
transform | ✅ | 透传 camelCase;FRConvertUtils::TransformToArk 支持 matrix、perspective、rotate/rotateX/Y/Z、scale/scaleX/Y、translate/translateX/Y、skewX/skewY(其他类型打日志忽略) |
transform-origin |
transformOrigin | ❌ | 渲染端无该键 |
opacity |
opacity | ✅ | 透传生效 |
filter |
filter | ❌ | 映射存在但序列化白名单外被过滤,且渲染端无消费(双重失效)。blur(camelCase 内联键)仅 ImageView 消费内容模糊且存在 dp→px 单位换算 bug(半径被 density 放大);gaussianBlur 为死键(三处常量声明,全引擎零消费)。详见效果专项文档 §2.3 |
| — | linearGradient | ✅ | 由 background: linear-gradient(...) 简写生成(见 §3)。支持无角度(默认 180°)、命名方向(to top/right/bottom/left + 4 对角)、turn/rad/grad 单位、transparent/命名色色标,统一归一化为 CSS 度数;C++ 侧对非法角度有兜底。见效果专项文档 §2.2 |
3. 支持的简写属性与展开规则
StyleResolver.expandShorthands() 实现:
| 简写 | 展开规则 | 生效 |
|---|---|---|
margin / padding |
1 值全等;2 值 上下/左右;3 值 上/左右/下;4 值 TRBL | ✅ |
border |
拆出 borderWidth(px/rpx 数字)、borderStyle(solid/dashed/dotted/none)、borderColor |
✅ |
background |
纯色 → backgroundColor;linear-gradient( → linearGradient 对象(angle + colorStopList) |
✅ |
flex |
flex:1→grow:1 shrink:1 basis:0%;flex:1 0 auto;flex:none→0 0 auto;flex:auto→1 1 auto |
✅ |
border-radius |
1 值→四角;2 值→对角组,展开为 4 个 per-corner longhand | ✅ |
box-shadow / text-shadow / text-decoration |
无拆分逻辑,映射为单个字符串键 | ❌(见 §2.4/§2.5) |
4. 支持的 CSS 单位
StyleResolver.convertValue():
| 单位 | 处理 |
|---|---|
px |
直接解析为数字 |
rpx |
编译期由 Rust 编译器转为 vw(value × 100 / 750,rpx_ratio=750);编译后残留的 rpx(如内联/运行时 setStyle)原样透传给 C++ 按 density 换算 |
vw / vh |
按 FlexUI.device.window.width/height(即 卡片容器尺寸)百分比计算 |
% |
原样透传给 Yoga/Taitank,按父容器解析 |
rem |
固定基准 16(REM_BASE),num × 16 |
| 无单位数字 | 解析为 number(line-height 例外,见 §2.5 倍数语义) |
em / ex / ch / pt / cm / mm / in |
❌ 原样透传字符串,结果不可预期 |
⚠️ vw/vh 基准是卡片容器而非屏幕:
getDimensions()取FlexUI.device.window.width。 曾有改为 screen 基准的尝试,内容放大 ~43% 溢出崩溃(见docs/bugfix/vw-screen-reference-crash.md),当前保持容器基准。
5. 支持的颜色格式
parseColor() / parseCSSColor():
#RGB/#RRGGBB(3/6 位十六进制)rgb(r,g,b)/rgba(r,g,b,a)- CSS 命名色(
red、transparent、white等,经原生FlexUI.Native.parseColor) - 统一转换为 ARGB int32(
0xAARRGGBB)
6. 属性继承
- 仅 Text / Span / View 三类元素参与继承(
TEXT_ELEMENT_NAMES)。 - 继承属性(
INHERIT_PROPS):color、fontSize、fontWeight、fontFamily、fontStyle、textAlign、lineHeight。 line-height倍数语义继承(见 §2.5)。
7. 支持的选择器与特异性
CSSManager 仅支持单层简单选择器:
| 选择器 | 特异性 | 说明 |
|---|---|---|
* |
0 | universal |
tag |
1 | type(view、text 等) |
.class |
10 | class |
#id |
100 | id |
.C--card |
10 | scoped class:C-- 前缀表组件作用域,运行时 bindPathScope(path, scopeId) 绑定后才生效 |
| 分组(逗号分隔) | 取最高 | loader splitSelectors 支持(含 :not(...) 括号内逗号) |
合并规则:特异性升序合并,低优先级先写、高覆盖;同特异性按声明顺序(后声明优先)。
作用域匹配:全局(scopeId=0),或 styleScope/hostScope 等于规则绑定 scope;未绑定 scoped 规则(scopeId=-1)永不匹配。
8. 组件默认样式(defaultNativeStyle,优先级最低)
定义于 flexui-backend/src/adapters/*-adapter.ts:
| 组件 | 默认样式 |
|---|---|
view |
无(空) |
text / span / label / p |
color: 0xFF000000 |
a |
color: 0xFF0000EE |
input / textarea |
padding: 0、color: 0xFF000000 |
image |
backgroundColor: 0 |
scroll-view |
flexDirection: 'column'、overflow: 'scroll' |
map |
width: '100%'、height: 300 |
ul |
flex: 1 |
canvas |
width: 300、height: 150(对齐微信 tip;可被 style/class 覆盖) |
9. 不支持的 CSS(完整清单)
9.1 不支持的属性
映射表存在、但渲染端不消费(CSS 简写不生效,改用 camelCase 分键)
| CSS 属性 | 原因 / 替代 |
|---|---|
box-shadow |
C++ 只认 shadowColor/shadowOffset(X/Y)/shadowOpacity/shadowRadius(camelCase) |
text-shadow |
C++ 只认 textShadowColor/textShadowOffset/textShadowRadius |
text-decoration |
C++ 只认 textDecorationLine/textDecorationColor/textDecorationStyle |
word-spacing、white-space、text-indent、text-overflow、word-break |
渲染端无对应键(breakStrategy/textOverflowMode 需 camelCase 或组件属性) |
background-position(合并形式)、background-repeat、background-origin、background-clip |
只认 position-x/y、size、image 分键 |
transform-origin |
渲染端无该键 |
filter |
序列化白名单外被过滤 + 渲染端无消费;blur 仅 Image 且单位 bug;gaussianBlur 死键(见效果专项文档 §2.3) |
-wx-line-clamp |
用 max-lines / maxLines 属性(→ numberOfLines) |
overflow-x / overflow-y |
用 overflow |
min-width / max-width / min-height / max-height(kebab 形式) |
用 camelCase minWidth 等(kebab 不映射,C++ 只认 camelCase) |
完全不支持(无映射、无消费)
- 布局:
gap/row-gap/column-gap(flex 间距,用 margin 代替)、flex-flow、全部grid-*、position: fixed/sticky、float/clear、inset - 文本:
font-variant、font-stretch、font-kerning、text-transform、text-justify、direction/unicode-bidi(排印语义) - 效果:
background-blend-mode、mix-blend-mode、backdrop-filter - 动画/交互:
transition全部、animation全部(引擎动画走 JS 驱动animationId/animationValue,无@keyframes)、cursor、pointer-events、user-select、touch-action - 其他:
content(伪元素专属)、visibility: hidden(仅display:none生效)、CSS 变量(--x定义与var(--x)均无效)
9.2 不支持的选择器
- 组合选择器:后代(
.a .b)、子(.a > .b)、相邻/兄弟(+/~)——不命中任何索引,静默失效 - 伪类:
:hover、:active、:focus、:nth-child()、:first-child、:not()等(hover 态请用hover-class属性) - 伪元素:
::before、::after、::placeholder - 属性选择器:
[attr=value]等(:host编译期转[wx-host=...],但 CSSManager 无属性索引,实际不生效;作用域隔离依赖 scoped class) :host与其它选择器组合(编译期告警忽略,HostSelectorCombination)
9.3 不支持的 at-rule
| at-rule | 状态 |
|---|---|
@media |
编译期保留为 MediaRule,运行时被 CSSManager 直接跳过("media query skipped (Phase 2)")——含 prefers-color-scheme、min-width/max-width 断点、orientation 等全部媒体查询 |
@keyframes |
被 rulejson loader 当 media 处理,运行时跳过 |
@supports / @document |
编译期原样包裹输出,无运行时求值 |
@font-face |
无处理 |
@import |
编译期内联(须位于样式表开头,否则告警 IllegalImportPosition) |
@charset |
编译期透传 |
9.4 不支持的函数与单位
calc():编译期仅做内部 rpx→vw 转换(in_calc选项),运行时不求值,表达式原样透传var()、attr()、env()、min()/max()/clamp()radial-gradient()、conic-gradient()、repeating-linear-gradient()(仅linear-gradient()支持)url()仅限background-image;image-set()- 单位:
em、ex、ch、pt、cm、mm、in、dpi等
9.5 其他限制
- 深色模式:无
prefers-color-scheme(见 §9.3);JS 侧getTheme()恒'light';Platform.NightMode恒 false——卡片无法感知系统深浅色 - 响应式断点:无媒体查询 → 无 min-width 断点布局(pad/折叠屏形态适配只能靠宿主控制容器宽度做等比缩放)
- 字体加载:无
@font-face,仅系统字体 / 宿主注入字体 visibility: hidden:不生效,仅display: none能隐藏
10. 已知行为修正(引擎自动处理,无需业务注意)
display:flex未指定flex-direction时强制row(对齐 W3C 默认,Yoga 默认 column)align-items/align-self/align-content: normal归一为stretch- 百分比尺寸 flex 子元素,父
align-items非 stretch 时自动补alignSelf:stretch display未知值静默丢弃(避免原生报错)- 卡片根元素:高度按内容 wrap-content(剥离
100%/100vh全屏高),宽度回退容器宽度(ROOT-DIM-FIX) - 文字内容折叠进 Text 载体
text属性,不创建子原生节点(避免 "CreateRenderView failed, span" 崩溃)
11. 组件特有属性(非 CSS,供对照)
CSS 之外,各组件 adapter 通过 attributeMaps 支持小程序风格属性(非完整列表):
| 组件 | 属性 |
|---|---|
text |
max-lines / maxLines → numberOfLines、ellipsize-mode → ellipsizeMode、overflow → textOverflowMode |
image |
src、mode(scaleToFill/aspectFit/aspectFill/widthFix/heightFix → resizeMode)、lazy-load 等 |
scroll-view |
scroll-x / scroll-y → 轴收口、scroll-left/scroll-top → contentOffset、show-scrollbar、scroll-with-animation、scroll-into-view、threshold 等 |
input / textarea |
value、placeholder、placeholder-text-color、editable、maxlength、focus、type、multiline 等 |
button / a |
点击类事件(tap/click 等,eventNamesMap 映射) |
canvas / map |
组件专属能力(绘图 API / 地图模块) |
12. 证据来源
| 环节 | 文件 |
|---|---|
| 属性映射表 / 单位 / 简写 / 继承 | flexui-engine/driver/js/packages/flexui-backend/src/native-backend/StyleResolver.ts |
| 选择器索引与作用域 | flexui-engine/driver/js/packages/flexui-backend/src/native-backend/CSSManager.ts |
| 窗口尺寸与根元素修正 | flexui-engine/driver/js/packages/flexui-backend/src/native-backend/NativeBackendContext.ts |
| CSS → RulesJSON(构建期) | toolkit/flexui-webpack-plugin/css-rulejson-loader.js |
| WXSS 编译(rpx、类前缀、:host、@import) | toolkit/flexui-stylesheet-compiler/src/lib.rs、step.rs、output.rs |
| 组件默认样式 / 属性映射 | flexui-engine/driver/js/packages/flexui-backend/src/adapters/*-adapter.ts |
| 布局键常量 | flexui-engine/dom/include/dom/node_props.h |
| 渲染端视图键常量 | flexui-engine/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/dom_node/fr_node_props.h |
| 渲染端样式消费(ArkUI) | flexui-engine/framework/ohos/src/main/cpp/impl/renderer/native/src/components/base_view.cc、rich_text_view.cc、rich_text_span_view.cc、src/utils/fr_convert_utils.cc |
| 布局引擎 | flexui-engine/dom/src/taitank_layout_node.cc、yoga_layout_node.cc |
| vw 基准说明 | docs/bugfix/vw-screen-reference-crash.md |
参考(非实现依据):上游 Hippy 样式文档
docs/engine/api/hippy-vue/style.md描述 Hippy 通用能力,与当前 fork 实际实现存在差异,以本文档为准。