作品外观
theme.css 与可视化编辑器、四套内置主题、作品自带的 CSS 与字体,以及正文里的 font 与 class 标签。
Kiny 作品最终渲染成网页,所以外观就是 CSS。把 .css 或字体文件放进项目就生效——不需要在任何地方声明。
换外观分两级:改一组变量,或者直接写选择器。
第一级:改 theme.css 里的变量
新建项目自带一个 theme.css(项目根),改它就换掉整个阅读页的外观:
.player {
--kiny-page-bg: #14110e;
--kiny-text: #efe6d8;
--kiny-prose-font: "楷体", serif;
--kiny-content-max-width: 720px;
}
在编辑器里点开 theme.css,看到的是一个可视化编辑器——配色、字体、字号行高、阅读栏宽直接拖着调,改完预览立刻换肤。想手写 CSS 就切到「原文」页,同一个文件两个视图。调整只改动对应的那几个值,你写的注释与自定义样式原样保留。
已有的老项目在编辑器里新建一个名为 theme.css 的文件,就得到同一份模板;另建的其它 .css 只给一个注释空壳,用来写选择器。
可改的变量
| 变量 | 含义 | 默认值 |
|---|---|---|
--kiny-page-bg |
页面底色 | #0d1117 |
--kiny-text |
正文文字色 | #e8e8e8 |
--kiny-prose-font |
正文字体族 | system-ui, "Noto Sans SC", sans-serif |
--kiny-prose-size |
正文字号 | 1.05rem |
--kiny-prose-line-height |
行高 | 1.9 |
--kiny-content-max-width |
阅读栏宽 | 680px |
--kiny-bg-overlay |
氛围底图的压暗遮罩(没设底图时不生效) | rgba(10, 14, 20, .55) |
--kiny-control-bg |
选项按钮 / 输入框底色 | rgba(255, 255, 255, .06) |
--kiny-control-bg-hover |
同上,悬停态 | rgba(255, 255, 255, .14) |
--kiny-control-text |
控件文字色 | #fff |
--kiny-control-border |
控件描边色 | rgba(255, 255, 255, .35) |
--kiny-accent |
强调色(推进提示等) | rgba(255, 255, 255, .8) |
--kiny-error |
错误文字色 | #ff8585 |
--kiny-panel-bg |
固定区域底色 | transparent(不遮氛围底图) |
--kiny-panel-text |
固定区域文字色 | 由正文色降一档推导 |
--kiny-panel-border |
固定区域发丝线色 | 由正文色推导 |
赋值即生效,不需要了解阅读页的 DOM 结构。
以
.player为根写,不要用:root。 声明直接落在阅读区元素本身,优先于从根元素继承下来的宿主(阅读器 / 网页书库 / 编辑器)皮肤取值;而且不会漏到编辑器界面上。默认值就是播放层的原生外观。各个宿主会先用自己的皮肤覆盖同名变量,作品的 CSS 再覆盖之——作品说了算。
变量赋值集中在一个文件里
同一个变量在多个 .css 里都赋值时,路径字典序靠后的那个生效——分散着写很容易互相盖掉。所以 token 赋值都放 theme.css,另建的 .css 只写选择器。
内置主题
编辑器里备了四套:石墨夜、暖纸、午夜蓝、素白。一键换整体风格,换完就是往 theme.css 里写了一组值——之后照样可以接着微调。
第二级:直接写选择器
作品 CSS 不限属性、不限选择器:媒体查询、伪类、动画都能用。
几个稳定的钩子:
| 选择器 | 对应 |
|---|---|
.panel-left / .panel-right / .panel-bottom / .panel-after |
@panel 的四个固定区域 |
.kin-illustration |
@img 插图(每张都带) |
.kin-divider |
@divider 分割线(每条都带) |
.kin-<名> |
正文里 <class=名> 挂的类(渲染时加 kin- 前缀) |
.player .panel-bottom { background: rgba(0, 0, 0, .3); }
.player .kin-illustration { border-radius: 8px; }
.player .kin-whisper { opacity: .7; font-style: italic; }
务必带
.player前缀。 不带会漏到宿主界面上,编辑器预览里尤其明显。
项目里的 CSS 与字体
.css:项目内任意位置的 .css 都会自动加载,按路径字典序注入。需要控制先后就用 10- / 20- 文件名前缀;不想让某个文件生效,把扩展名改掉(如 skin.css.bak)。
字体文件(.woff2 / .woff / .ttf / .otf):自动注册 @font-face,族名 = 文件名去掉扩展名。把 楷体.woff2 丢进项目任意位置,直接就能用:
.player { --kiny-prose-font: "楷体", serif; }
信纸上写着:<font=楷体>见字如晤。</font>
不需要写 @font-face。一个文件一个族;族名非法(含 ; ( ) " ' 等)会被忽略;同名族按路径序后者覆盖。
发现规则:跳过以 . 开头的路径段与 node_modules。图片、音频不参与自动加载——被 CSS 的 url() 或演出命令引用即可。CSS 里的相对 url() 以该 CSS 文件所在目录为基准解析。
只有
.css与字体自动加载。.js/.json/.md/.txt/.html同样能放在项目里、也能在编辑器里编辑,但不参与自动加载——尤其.js不会被执行。
正文里的两个钩子
正文写作里讲过的两个标签,是把样式从正文交给样式表的正规方式:
<font=名>—— 换字体族。族名是项目里自动注册的字体,或系统字体名。找不到就回退到正文默认字体,不影响阅读。<class=名>—— 挂一个语义类,渲染时加kin-前缀,交给作品 CSS 定义。嵌套的<class>累积生效(外层letter+ 内层old同时挂上)。类名覆盖整行时挂到行容器上(背景、边框、内边距这类块级样式完整可用),只包片段时挂在那个片段上。
<class=letter>信纸上写着:<class=old>见字如晤。</class></class>
.player .kin-letter { background: #f5efe0; padding: 12px 16px; }
.player .kin-old { font-family: "楷体", serif; opacity: .85; }
行内标签的取值受限、作品 CSS 完全开放,这是两件事。 行内标签是正文里的标记,取值经严格校验以杜绝经正文注入样式;作品 CSS 是你自己的样式表,任意属性与选择器都能写。
<class=名>正是把样式钩子从正文交给样式表的那道门。
到处都一样
外观随作品分发,在所有播放的地方生效:编辑器预览、桌面阅读器、网页书库、导出的独立网页。你在预览里看到的,就是读者看到的。
接下来
语言部分到这里就全了。往下是「用编辑器」与「发布与阅读」两部分——怎么写得更顺手,以及怎么把作品交到读者手里。