PSUIP 布局语法
📋 更新历史
| 日期 | 版本 | 更新内容 |
|---|---|---|
| 2025-11-06 | v1.1.0 | 新增 layout 自定义属性支持、新增 bgColumn 带样式容器 |
| 2025-08-15 | v1.0.0 | 初始版本 |
PSUIP 支持将标准 Markdown 内容划分为多个层级,并提供灵活的布局控制语法,允许开发者创建复杂的页面布局结构。
布局层级概念
PSUIP 将 Markdown 内容解析为层级结构,类似于 HTML 的 DOM 结构。以下面的 Markdown 内容为例:
## 二级标题
### 三级标题1
### 三级标题2
[主要按钮](https://example.com)其层级关系相当于以下 DOM 结构:
<section>
<h2>二级标题</h2>
<section>
<h3>三级标题1</h3>
<h3>三级标题2</h3>
<button>主要按钮</button>
</section>
</section>布局语法规范
基本语法结构
布局标签采用 XML 风格的语法:
<layout:布局类型>
内容区域
</layout:布局类型>嵌套规则
- 布局标签可以嵌套使用
- 内层布局会覆盖外层布局的方向设置
- 布局标签必须成对出现
- 支持多层级嵌套
支持的布局类型
1. 列布局 (Column Layout)
语法:<layout:column></layout:column>
特性:
- 垂直排列内部元素
- 这是默认的布局方式
- 每个元素占据一行
示例:
## 产品介绍
<layout:column>
### 功能特性
### 技术优势
[了解更多](https://example.com)
</layout:column>等效 CSS:
.layout-container {
display: flex;
flex-direction: column;
}2. 行布局 (Row Layout)
语法:<layout:row></layout:row>
特性:
- 水平排列内部元素
- 元素在同一行显示
- 自动分配空间
示例:
## 导航菜单
<layout:row>
### 首页
### 产品
### 关于我们
[联系我们](https://example.com)
</layout:row>等效 CSS:
.layout-container {
display: flex;
flex-direction: row;
}3. 画廊布局 (Gallery Layout)
语法:<layout:gallery></layout:gallery>
特性:
- 瀑布流布局
- 默认两列显示
- 适合卡片容器展示
- 自动平衡内容高度
示例:
## 产品展示
<layout:gallery>
### 产品A
产品A的详细介绍...
### 产品B
产品B的详细介绍...
### 产品C
产品C的详细介绍...
</layout:gallery>等效 CSS:
.layout-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}4. 带样式背景列布局 (Background Column Layout) v1.1.0 新增
语法:<layout:bgColumn></layout:bgColumn>
特性:
- 竖向布局容器
- 支持背景色设置
- 带边框和阴影效果
- 支持自定义样式属性
- 适合多卡片容器内展示
默认样式:
- 带圆角边框
- 浅色背景
- 轻微阴影效果
- 垂直方向排列
示例:
<layout:bgColumn background={color.onprimary.white100}>
<layout:row>
<card:elegantStandard></card:elegantStandard>
<card:elegantList></card:elegantList>
</layout:row>
</layout:bgColumn>使用场景:
- 多卡片组合展示
- 需要视觉区分的内容区域
- 强调特定内容模块
- 创建卡片组合布局
等效 CSS:
.layout-container {
display: flex;
flex-direction: column;
padding: 12px;
border-radius: 16px;
box-shadow: 0 1px 8px 0 rgba(31, 31, 42, 0.15);
border: 1px solid rgba(0, 0, 0, 0.12);
background: #ffffff;
}高级布局模式
混合布局
通过嵌套使用不同的布局类型,可以创建复杂的页面结构:
## 页面标题
<layout:row>
### 左侧区域
<layout:column>
#### 子标题1
#### 子标题2
[操作按钮](https://example.com)
</layout:column>
### 右侧区域
<layout:column>
#### 子标题3
#### 子标题4
[secondary][辅助按钮](https://example.com)
</layout:column>
</layout:row>等效 DOM 结构:
<section>
<h2>页面标题</h2>
<section style="display:flex;flex-direction:row">
<section>
<h3>左侧区域</h3>
<section style="display:flex;flex-direction:column">
<h4>子标题1</h4>
<h4>子标题2</h4>
<button>操作按钮</button>
</section>
</section>
<section>
<h3>右侧区域</h3>
<section style="display:flex;flex-direction:column">
<h4>子标题3</h4>
<h4>子标题4</h4>
<button>辅助按钮</button>
</section>
</section>
</section>
</section>分栏布局
创建经典的分栏布局:
## 文章标题
<layout:row>
<layout:column>
### 主要内容
这里是文章的主要内容区域,包含详细的文字描述和说明。
#### 重点信息
- 要点1
- 要点2
- 要点3
</layout:column>
<layout:column>
### 侧边栏
#### 相关链接
[链接1](https://example.com)
[链接2](https://example.com)
#### 推荐阅读
- 推荐文章1
- 推荐文章2
</layout:column>
</layout:row>网格布局 (画廊模式)
画廊布局特别适合展示卡片式内容:
## 团队成员
<layout:gallery>
### 张三
前端开发工程师
专注于用户界面设计和交互体验优化。
### 李四
后端开发工程师
负责服务器架构设计和数据库优化。
### 王五
产品经理
负责产品规划和用户需求分析。
### 赵六
UI/UX 设计师
专注于用户体验设计和视觉设计。
</layout:gallery>响应式设计
自动适配
所有布局都支持响应式设计:
- 桌面端:按照指定布局显示
- 平板端:行布局可能转为列布局
- 移动端:所有布局默认转为列布局
断点设置
系统内置响应式断点:
- 大屏:> 1200px
- 桌面:768px - 1200px
- 平板:576px - 768px
- 手机:< 576px
布局最佳实践
1. 合理选择布局类型
- 列布局:适合垂直信息流,如文章、列表
- 行布局:适合导航、按钮组、简短内容
- 画廊布局:适合卡片展示、产品列表
2. 避免过度嵌套
<!-- 不推荐:过度嵌套 -->
<layout:row>
<layout:column>
<layout:row>
<layout:column>
内容
</layout:column>
</layout:row>
</layout:column>
</layout:row>
<!-- 推荐:简洁结构 -->
<layout:row>
<layout:column>
内容A
</layout:column>
<layout:column>
内容B
</layout:column>
</layout:row>3. 考虑内容比例
在行布局中考虑内容的长度和比例:
<layout:row>
<!-- 短标题 -->
### 简介
<!-- 长内容应该单独成列 -->
<layout:column>
### 详细说明
这里是很长的内容描述,包含大量的文字和详细信息...
</layout:column>
</layout:row>4. 语义化布局
布局应该服务于内容的语义结构:
## 产品对比
<layout:row>
### 产品A
<layout:column>
#### 功能特性
- 特性1
- 特性2
#### 价格信息
$99/月
</layout:column>
### 产品B
<layout:column>
#### 功能特性
- 特性1
- 特性2
#### 价格信息
$199/月
</layout:column>
</layout:row>错误处理
常见错误
-
标签不匹配
<!-- 错误 --> <layout:row> 内容 </layout:column> <!-- 正确 --> <layout:row> 内容 </layout:row> -
嵌套错误
<!-- 错误:交叉嵌套 --> <layout:row> <layout:column> </layout:row> </layout:column> <!-- 正确:正确嵌套 --> <layout:row> <layout:column> </layout:column> </layout:row> -
空布局
<!-- 不推荐:空布局 --> <layout:row> </layout:row> <!-- 推荐:有意义的内容 --> <layout:row> ### 有效内容 </layout:row>
错误恢复
当遇到布局语法错误时,系统会:
- 忽略错误的布局标签
- 使用默认的列布局
- 在控制台输出警告信息
- 保持内容的正常显示
布局自定义属性 v1.1.0 新增
PSUIP 支持为布局容器添加自定义样式属性,通过设计令牌(Design Token)系统实现灵活的样式定制。
语法规范
<layout:类型 属性名="属性值"></layout:类型>支持自定义属性的布局类型
不同的布局类型支持不同的自定义属性集合,具体支持的属性由 styleConfig 中的 supportedAttributes 字段定义。
layout:root 支持的属性
layout:root 是页面的根布局容器,支持以下属性:
| 属性名 | 说明 | 示例值 |
|---|---|---|
backgroundImage | 背景图片 | url(https://example.com/bg.jpg) |
backgroundRepeat | 背景重复方式 | no-repeat, repeat, repeat-x, repeat-y |
backgroundSize | 背景尺寸 | cover, contain, 100% 100% |
backgroundPosition | 背景位置 | center, top left, 50% 50% |
backgroundColor | 背景颜色 | #ffffff, {color.surface.grey0} |
background | 背景综合属性 | linear-gradient(...) |
示例:设置背景图片
<layout:root backgroundImage="url(https://cdn.pixabay.com/photo/2016/05/05/02/37/sunset-1373171_1280.jpg)" backgroundSize="cover" backgroundPosition="center">
## 欢迎页面
这是一个带有背景图片的页面
</layout:root>示例:设置背景色
<layout:root backgroundColor="{color.surface.grey1}">
## 内容区域
浅灰色背景的内容区域
</layout:root>layout:bgColumn 支持的属性
layout:bgColumn 作为带样式的布局容器,支持丰富的样式属性:
| 属性名 | 说明 | 示例值 |
|---|---|---|
background | 背景(颜色/渐变) | {color.primary.brand3}, linear-gradient(...) |
backgroundColor | 背景颜色 | {color.onprimary.white100} |
padding | 内边距 | {dimension.padding.base}, 20px |
margin | 外边距 | {dimension.margin.loose}, 10px 20px |
borderRadius | 圆角半径 | {dimension.borderradius.large}, 16px |
borderColor | 边框颜色 | {color.surfacecontainer.black12} |
borderWidth | 边框宽度 | {dimension.borderwidth.narrow}, 1px |
boxShadow | 阴影效果 | {material.hierarchy.main} |
示例:自定义 bgColumn 样式
<layout:bgColumn
background="{color.primarycontainer.brand1}"
padding="{dimension.padding.extraloose}"
borderRadius="{dimension.borderradius.xl}">
<card:elegantStandard>
## 卡片标题
卡片内容...
</card:elegantStandard>
</layout:bgColumn>设计令牌引用
自定义属性支持两种值的形式:
-
设计令牌引用:使用
{token.path}格式background="{color.primary.brand4}" -
直接 CSS 值:使用标准 CSS 值
padding="20px" backgroundColor="#f0f0f0"
推荐使用设计令牌,以保持样式的一致性和主题化能力。
属性值解析规则
- URL 值:以
url(开头的值会被识别为 URL,直接使用 - 颜色值:以
#开头的值会被识别为颜色,直接使用 - 像素值:以
px结尾的值会被识别为像素单位,直接使用 - 百分比值:以
%结尾的值会被识别为百分比,直接使用 - 关键字:
none,auto等 CSS 关键字会被直接使用 - 令牌引用:以
{开头和}结尾的值会被解析为设计令牌路径
组合使用示例
<layout:root
backgroundImage="url(https://example.com/pattern.png)"
backgroundRepeat="repeat"
backgroundSize="100px 100px">
<layout:bgColumn
background="{color.surfacecontainer.white88}"
padding="{dimension.padding.superloose}"
boxShadow="{material.hierarchy.2f}">
<layout:row>
<card:elegantStandard>
## 左侧卡片
内容...
</card:elegantStandard>
<card:elegantStandard>
## 右侧卡片
内容...
</card:elegantStandard>
</layout:row>
</layout:bgColumn>
</layout:root>注意事项
- 属性验证:只有在
supportedAttributes列表中的属性才会被应用,不支持的属性会被忽略并在控制台输出警告 - 令牌解析:设计令牌如果找不到对应值,会使用原始字符串
- 优先级:自定义属性会覆盖默认样式
- 性能考虑:避免使用过大的背景图片,建议使用优化后的图片资源
兼容性说明
- 布局语法是 PSUIP 的扩展特性
- 不使用布局标签时,内容按默认列布局显示
- 所有布局都支持标准 Markdown 元素
- 布局标签不会影响标准 Markdown 的解析
- 自定义属性是可选的,不使用时使用默认样式