# Ionic Framework 设计系统

## Ionic Framework 设计系统界面预览

切换字体、使用键盘调整字号、切换暖色纸张底色，并保存本地偏好设置快照。

## Ionic Framework 设计系统设计参考

已验证 Ionic Vue/Core 9.0.6。核心颜色取自已安装的 core.css。演示明确选择 iOS 模式。阅读排版、纸张颜色和周边间距均为应用自身的设计选择，并非 Ionic 默认值。

### 浅色主题的默认语义颜色角色

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| --ion-color-primary | #0054e9 | 原生主要控件。 |
| --ion-color-primary-rgb | 0, 84, 233 | 用于基于不透明度进行计算的 RGB 通道值。 |
| --ion-color-primary-contrast | #fff | 主要颜色上的文本与图标对比度。 |
| --ion-color-primary-shade | #004acd | 加深后的主要颜色变体。 |
| --ion-color-primary-tint | #1a65eb | 提亮后的主要颜色变体。 |
| --ion-color-secondary | #0163aa | 次要角色。 |
| --ion-color-tertiary | #6030ff | 第三级颜色角色。 |
| --ion-color-success | #2dd55b | 成功角色。 |
| --ion-color-warning | #ffc409 | 警告角色。 |
| --ion-color-danger | #c5000f | 危险角色。 |
### 按模式区分的原生范围控件尺寸

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| iOS --bar-height | 4px | 编译后的 iOS 范围控件默认值。 |
| iOS --knob-size | 26px | 编译后的 iOS 滑块尺寸。 |
| MD --bar-height | 2px | 编译后的 Material Design 模式默认值。 |
| MD --knob-size | 18px | 编译后的 Material Design 滑块尺寸。 |
| Application min / max / step | 16 / 26 / 1 | 整数形式的阅读字号；对应实际范围控件属性。 |
| snaps / ticks / pin | true / true / true | 显示刻度和格式化后的字号反馈。 |
### 原创阅读与布局比例

| 名称 / 规则 | 值 / 配置 | 用途 |
| --- | --- | --- |
| Reading font | Georgia, serif OR system-ui, sans-serif | 由原生分段控件控制；字体取自设备已有字体。 |
| Reading size | 16–26px; default 18px | 直接应用于文章。 |
| Reading line-height | 1.65 | 原创的舒适正文行宽。 |
| Article heading | 1.9em / 1.15; 1.6em below 360px | 随读者选择的正文大小缩放。 |
| Control/body font | system-ui, sans-serif | 明确指定应用字体。 |
| Spacing | 10 / 12 / 14 / 16 / 20 / 22 / 24 / 28 / 32px | 具体的原创样式表数值，并非声称属于 Ionic 的比例系统。 |
| Layout | 300px settings + flexible article; stack at 760px | 两列均使用 min-width:0。 |
| Paper roles | #fff9eb warm; #ffffff white; #24362e ink | 原创内容颜色，与原生控件角色分开设置。 |
| Card radius | 16px | 原创的外围面板尺寸。 |
## Ionic Framework 设计系统完整指南

实用指南，介绍如何为真实界面选择、应用和评审此系统。

完整指导、实现起点和源代码链接。

## Ionic Framework 设计系统：审慎选择渲染模式

### 审慎选择渲染模式

> Ionic 通过框架集成提供 Web 组件。此示例使用 Ionic Vue 9.0.6，并在 IonicVue 配置中将 mode 设为 ios。这样一来，无论使用哪种桌面浏览器查看页面，segment、toggle、range 和按钮都能保持统一的平台风格。mode 是组件渲染方式的选择；它不会将页面变成原生移动应用。

此示例特意使用普通的 main 元素，而不是全屏的 IonApp/IonContent 外壳。这样，组件示例就能在嵌入式资源页面中按内容调整尺寸。实际的 Ionic 路由应用应遵循框架的页面和路由结构，并在过渡效果需要时使用 IonPage。

阅读配套规范

## Ionic Framework 设计系统：Ionic 颜色由一组相关变量构成

### Ionic 颜色由一组相关变量构成

已安装的核心样式表将 primary 定义为 #0054e9，并提供单独的 RGB 通道、对比色、阴影色和浅色变体值。组件可在不同状态下使用这些相关值。只替换基础十六进制颜色可能导致其他状态不一致；自定义品牌色应定义完整的一组颜色值。

此示例保留了原生控件的默认 primary 颜色。暖纸色是单独的应用界面表面，颜色为 #fff9eb，文章文字则保持为 #24362e。将页面切换为白色只会改变阅读背景，不会悄然更改控件配色，也不代表实现了 Ionic 的完整深色配色方案。

阅读配套规范

## Ionic Framework 设计系统：让读者的字体选择效果清晰可见

### 让读者的字体选择清晰可见

此分段控件可在 Georgia 和 system-ui 之间切换文章字体。控件本身仍使用 system-ui，确保偏好设置只影响指定的阅读内容，不会意外改变标签和控件尺寸。示例不会请求外部字体，而是使用相应的本地字体栈。

文字大小为 16 到 26 像素之间的整数。文章标题按此字号进行比例缩放，行高保持为 1.65。在宽度小于 360px 时，标题的缩放比例降至 1.6em，因此即使嵌入栏较窄，最大字号仍然易于阅读。这些是应用自定义值，与 Ionic 组件默认值明确区分。

阅读配套规范

## Ionic Framework 设计系统：分段控件具有受控的选中状态和原生语义

### 分段控件应具备受控的选中状态和原生语义

IonSegment 接收当前的 face 值和两个 IonSegmentButton 子项。其 ionChange 事件会从 event.detail.value 更新模型。每个按钮都有不同且稳定的值：serif 或 sans，显示标签则说明对应选项。使用 aria-labelledby 为整个控件提供标签。

实际的无障碍树会将其呈现为包含已选中标签的 tablist，而不是普通按钮组。因此，本地交互测试会定位原生的“无衬线”标签页，并验证阅读字体随之改变。仅仅将两个按钮样式设计成分段控件的外观，并不能实现相同的选中行为。

阅读配套规范

## Ionic Framework 设计系统：将范围事件和约束作为一套完整约定

### 将范围控件事件和约束作为统一契约

IonRange 明确设置 min、max 和 step；依赖其默认的 0 到 100 范围，无法表达实用的阅读字号。启用吸附和刻度可以显示可选步进值，pin 格式化函数则会在交互时显示的数值后追加 px。拖动结束后，控件下方持续显示的字号标签仍清晰可读。

事件处理程序使用 ionChange，并将其值转换为数字。这适用于单滑块；双滑块范围会返回不同形态的值，需要单独处理。编译后的 iOS range 使用 26 像素滑块和 4 像素轨道，而 Material 模式使用 18 像素和 2 像素。这些差异会如实记录，不会被简化成虚构的通用 Ionic 令牌。

1. 聚焦字号滑块，按 8 次右箭头键，将字号调至 26px。

2. 选择“无衬线”，并关闭“暖纸色”。

3. 保存偏好设置，并核对快照中的确切字体、字号和纸张样式。

阅读配套规范

## Ionic Framework 设计系统：布尔值控制的纸张选项应立即更新界面表面

### 切换纸张底色时，应立即更新界面

IonToggle 从 warm 模型接收 checked 值。其事件会提供 detail.checked，并将其直接赋给对应的布尔状态。可见标签“暖纸色”属于原生开关，旁边的说明则告知读者此选项会改变文章背景。

warm 类会改变文章背景，但保留边框和文章内容，使对比具有意义。这样也能避免将纸张色调偏好与平台级的浅色/深色设置混为一谈；后者需要协调更多 Ionic 界面表面和文字变量。

阅读配套规范

## Ionic Framework 设计系统：将已应用的偏好设置与已保存的快照区分开

### 区分已应用的偏好设置与已保存的快照

每项设置都会立即应用于文章。“保存偏好设置”会在本地响应式状态中记录一份易读的快照，并在快照与当前设置一致时禁用按钮。对三个模型进行监听；任何一项发生变化，都会清除提示，避免旧的确认信息描述新的组合。

“恢复默认设置”会恢复 serif、18 像素和暖纸色，然后清除已保存的提示。状态说明明确指出，这些偏好设置仅应用于此预览。此操作背后没有 localStorage 持久化、账户设置或原生偏好设置插件；重新加载后会恢复默认值。

阅读配套规范

## Ionic Framework 设计系统：保留原生 Shadow DOM 控件，同时为整体布局添加样式

### 保留原生 Shadow DOM 控件，同时为整体布局添加样式

range 带有可见的“字号”标签，toggle 内含文字标签，segment 则标记为“字体”。原始插图设为 aria-hidden。保存反馈使用 role=status，文章仍是普通的语义化 HTML，因此其中的标题和段落可遵循读者常规的文档导航方式。

Ionic 组件会将内部标记封装在 Shadow DOM 中。本示例使用公开属性、事件和文档中说明的 CSS 自定义属性，而不是查询私有内部类。外围页面采用内容高度和零最小宽度；在 280px 宽度下检查，可以发现独立手机截图可能遗漏的嵌入式宽度问题。

- 在原生组件上保留标签关联关系。

- 使用公开属性和事件，而不是修改 Shadow DOM 内部结构。

- 同时检查键盘尺寸变化和实时文章。

阅读配套规范

## Ionic Framework 设计系统：安装 Vue 集成并引入核心 CSS

### 安装 Vue 集成并引入 Core CSS

完整入口会注册 IonicVue，并在原始样式表之前导入 @ionic/vue/css/core.css。已安装的 Vue 包也会解析 vue-router，因此可复现的依赖安装命令中包含 vue-router，尽管这个嵌入式示例并未配置导航。遗漏该对等依赖会导致本地打包时无法解析依赖。

两个完整示例提供了 App.vue 和 style.css。标准 Vite Vue 项目会编译单文件组件（SFC）及其原生组件导入。独立资源预览会在本地打包生成的 JavaScript 和 CSS，包括组件实现，因此更改控件无需请求外部 CDN。

阅读配套规范

## Ionic Framework 设计系统组件示例

### 完整的阅读偏好 SFC

原生 IonSegment、IonRange、IonToggle 和 IonButton 用于控制一篇原创短文。

```
<script setup>
import {ref,computed,watch} from 'vue';
import {IonSegment,IonSegmentButton,IonLabel,IonRange,IonToggle,IonButton,IonChip} from '@ionic/vue';
const face=ref('serif'),size=ref(18),warm=ref(true),saved=ref('');
const family=computed(()=>face.value==='serif'?'Georgia, serif':'system-ui, sans-serif');
watch([face,size,warm],()=>saved.value='');
function save(){saved.value=`Saved locally: ${face.value}, ${size.value}px, ${warm.value?'warm':'white'} paper.`}
function reset(){face.value='serif';size.value=18;warm.value=true;saved.value=''}
</script>
<template>
<main class="reader-shell">
<header><p class="eyebrow">A QUIETER READING SPACE</p><h1>Make room for the words.</h1><p>Adjust this short essay to your reading preferences. The sample changes as you move the controls.</p></header>
<div class="reader-layout"><section class="preferences" aria-labelledby="preferences-title"><h2 id="preferences-title">Reading settings</h2><p class="label" id="face-label">Typeface</p>
<IonSegment :value="face" @ionChange="face=$event.detail.value" aria-labelledby="face-label"><IonSegmentButton value="serif"><IonLabel>Serif</IonLabel></IonSegmentButton><IonSegmentButton value="sans"><IonLabel>Sans</IonLabel></IonSegmentButton></IonSegment>
<IonRange :value="size" @ionChange="size=Number($event.detail.value)" :min="16" :max="26" :step="1" :snaps="true" :ticks="true" :pin="true" label="Text size" label-placement="stacked" :pin-formatter="v=>`${v}px`"/><p class="scale"><span>16px</span><strong>{{size}}px</strong><span>26px</span></p>
<div class="paper-toggle"><IonToggle :checked="warm" @ionChange="warm=$event.detail.checked" justify="space-between">Warm paper</IonToggle><p>Soft ivory or a white page. The controls keep their own contrast.</p></div>
<IonButton expand="block" @click="save" :disabled="!!saved">Save preferences</IonButton><IonButton expand="block" fill="clear" @click="reset">Restore defaults</IonButton><p class="save-result" role="status">{{saved||'Preferences apply to this preview only.'}}</p></section>
<article class="reading-paper" :class="{warm}" :style="{fontFamily:family,fontSize:size+'px'}"><div class="paper-art" aria-hidden="true"><span></span><i></i><b></b></div><p class="article-kicker">FIELD NOTES · 03</p><h2>The useful pause</h2><p>There is a small garden between the library and the river. Its benches face away from the busiest path, toward a row of young trees.</p><p>On an ordinary afternoon, the place asks very little. You can read a paragraph twice, let a conversation settle, or watch the shadow of a leaf move across the page.</p><p>Good reading spaces leave that choice with the reader. A comfortable line, a familiar letterform, and a little breathing room can make a page easier to return to.</p><footer><IonChip outline>Original sample essay</IonChip><span>{{size}}px · {{face==='serif'?'Georgia':'System sans'}} · 1.65 line height</span></footer></article></div>
</main>
</template>
```

代码参考

- 范围值通过 ionChange 提交；e.detail.value 会转换为数字。

- 更改任一偏好都会清除已保存的快照。

- 保存操作使用本地响应式状态，不涉及设备存储或服务器请求。

### 完整的原创布局样式表

采用内容高度嵌入式布局和窄屏纵向排列；读者可选择字体样式，无需访问组件的 Shadow DOM。

```
html,body,#app{height:auto;min-height:0;margin:0}*{box-sizing:border-box}body{font-family:system-ui,sans-serif;color:#24362e;background:#f2f5f3}.reader-shell{max-width:1120px;margin:auto;padding:32px}.eyebrow{font-size:11px;letter-spacing:.14em;font-weight:700;color:#52695c}h1{font-size:34px;line-height:1.15;max-width:660px;margin:12px 0}header>p:last-child{font-size:15px;line-height:1.6;max-width:660px;color:#56675e}.reader-layout{display:grid;grid-template-columns:300px minmax(0,1fr);gap:24px;margin-top:28px}.preferences{background:white;border:1px solid #dbe3de;border-radius:16px;padding:22px;align-self:start;min-width:0}.preferences h2{font-size:19px;margin:0 0 22px}.label{font-size:14px;font-weight:600;margin-bottom:10px}ion-segment{margin-bottom:20px}ion-range{padding:12px 0 0;--bar-height:4px}.scale{display:flex;justify-content:space-between;font-size:12px;color:#52695c;margin:0 0 24px}.paper-toggle{border-top:1px solid #e4e9e6;padding-top:20px;margin-bottom:20px}.paper-toggle ion-toggle{width:100%;font-size:14px}.paper-toggle p{font-size:12px;line-height:1.6;color:#5a6b61}.save-result{font-size:12px;line-height:1.6;color:#46614f;min-height:38px}.reading-paper{background:white;border:1px solid #dce3dd;border-radius:16px;padding:28px;line-height:1.65;min-width:0;overflow-wrap:anywhere;transition:background .2s}.reading-paper.warm{background:#fff9eb}.reading-paper h2{font-size:1.9em;line-height:1.15;margin:14px 0 24px;font-weight:400}.reading-paper p{margin:0 0 1.2em}.article-kicker{font-family:system-ui,sans-serif;font-size:10px;letter-spacing:.15em}.paper-art{height:112px;background:#dce8d9;border-radius:8px;position:relative;overflow:hidden;margin-bottom:24px}.paper-art span{position:absolute;width:150px;height:150px;background:#a4baa2;border-radius:50%;right:15%;top:35px}.paper-art i{position:absolute;width:130px;height:70px;background:#f3e0a8;border-radius:50% 50% 0 0;right:25%;top:48px}.paper-art b{position:absolute;width:60px;height:130px;transform:rotate(24deg);background:#64816b;left:15%;top:38px;border-radius:50% 50% 0 0}.reading-paper footer{font:11px/1.6 system-ui,sans-serif;border-top:1px solid #deded3;padding-top:18px;display:flex;gap:12px;flex-wrap:wrap;align-items:center}.reading-paper ion-chip{font-size:11px;margin:0}@media(max-width:760px){.reader-shell{padding:20px}.reader-layout{grid-template-columns:minmax(0,1fr)}h1{font-size:29px}}@media(max-width:360px){.reader-shell{padding:14px}.preferences,.reading-paper{padding:16px}.reader-layout{gap:18px}.reading-paper h2{font-size:1.6em}}
```

代码参考

- 范围控件使用文档中说明的 --bar-height 自定义属性。

- 所有文章插图均为原创 CSS，并标记为装饰性内容。

## Ionic Framework 设计系统 Agent 设置

### 实现起点

已验证 Ionic Vue/Core 9.0.6。完整 SFC 和样式表见上文；vue-router 作为集成依赖安装，但预览中没有路由页面。

```
// Start with: npm create vite@latest ionic-reader -- --template vue
// cd ionic-reader && npm install
// npm install @ionic/vue@9.0.6 @ionic/core@9.0.6 vue-router@4
// Save the complete examples as src/App.vue and src/style.css.
// src/main.js:
import {createApp} from 'vue';
import {IonicVue} from '@ionic/vue';
import '@ionic/vue/css/core.css';
import './style.css';
import App from './App.vue';
createApp(App).use(IonicVue, {mode:'ios'}).mount('#app');
// The Vite index.html must contain:
// <div id="app"></div><script type="module" src="/src/main.js"></script>
// Run: npm run dev
```

### 适用于你项目的提示词

```
使用 Ionic Vue/Core 9.0.6 的显式 iOS 模式，构建提供的阅读偏好示例。保留原生 Segment、Range、Toggle 和 Button 控件，并让它们分别控制字体选择、文本大小、纸张外观和文章样式。将字号范围维持在 16–26px，并在本地已保存的偏好快照中反映更改。包含 IonicVue 设置、所需的 CSS 和 vue-router 对等依赖；保留内容高度布局，不要在嵌入区域中添加全屏外壳。不会上传检查数据，也不会远程更改账户。
```

## Ionic Framework 设计系统来源与范围

Ionic Vue/Core 9.0.6，iOS 模式。原创短文、插图、阅读比例和暖纸色彩。保存使用本地响应式状态，不会在重新加载后保留。此嵌入式组件示例并非完整的路由应用或原生设备 Ionic 应用。

- Vue 集成 插件、组件导入和完整应用结构。

- 色彩系列 基础、对比、阴影、色调和 RGB 角色。

- CSS 变量 全局与组件自定义属性。

- 分段控件 选择模型与分段控件事件。

- 范围控件 标签、步进、刻度、标记和事件值结构。

- 切换开关 选中状态与更改事件。

- Button 展开、填充和禁用状态。

- Shadow Parts 支持的样式边界。

## Ionic Framework 设计系统相关资源

### Kobalte

Kobalte 为 Solid 提供无头组件，包括分别处理原始值和格式化值的数值输入框、复合复选框结构，以及带按下状态的按钮。本指南通过配方缩放器将这些基础组件与 Solid 信号结合起来，其中包含派生数量和可重置的食材勾选项。

### Mantine

以原生参与者表格和排期抽屉为核心的 Mantine 9 参考示例。查看实际主题比例，将 useForm 连接到 TextInput、Select、Checkbox 和 DatePickerInput，并在添加本地记录前试用验证功能。

### Melt UI

Melt UI 的 store/action 构建器可为你编写的 Svelte 标记添加无障碍行为。本指南使用 @melt-ui/svelte 0.86.6，通过属性、actions 和可写 stores 连接单选项、滑块和开关构建器；它不同于较新的 runes API。


- [实现参考](https://ionicframework.com/docs/vue/quickstart)
- [来源](https://ionicframework.com/docs/theming/colors)
- [来源](https://ionicframework.com/docs/api/range)
- [来源](https://ionicframework.com/docs/theming/css-variables)
- [阅读配套规范](https://ionicframework.com/docs/vue/quickstart)
- [阅读配套规范](https://ionicframework.com/docs/theming/colors)
- [阅读配套规范](https://ionicframework.com/docs/theming/css-variables)
- [阅读配套规范](https://ionicframework.com/docs/api/segment)
- [阅读配套规范](https://ionicframework.com/docs/api/range)
- [阅读配套规范](https://ionicframework.com/docs/api/toggle)
- [阅读配套规范](https://ionicframework.com/docs/api/button)
- [阅读配套规范](https://ionicframework.com/docs/theming/css-shadow-parts)
- [代码参考](https://ionicframework.com/docs/api/range)
- [代码参考](https://ionicframework.com/docs/theming/css-variables)
- [Vue 集成 插件、组件导入和完整应用结构。](https://ionicframework.com/docs/vue/quickstart)
- [色彩系列 基础、对比、阴影、色调和 RGB 角色。](https://ionicframework.com/docs/theming/colors)
- [CSS 变量 全局与组件自定义属性。](https://ionicframework.com/docs/theming/css-variables)
- [分段控件 选择模型与分段控件事件。](https://ionicframework.com/docs/api/segment)
- [范围控件 标签、步进、刻度、标记和事件值结构。](https://ionicframework.com/docs/api/range)
- [切换开关 选中状态与更改事件。](https://ionicframework.com/docs/api/toggle)
- [Button 展开、填充和禁用状态。](https://ionicframework.com/docs/api/button)
- [Shadow Parts 支持的样式边界。](https://ionicframework.com/docs/theming/css-shadow-parts)
