Templates
LAPLACE Chat 采用了现代的 CSS 架构,方便开发者对样式进行定制。配置器使用了 VS Code 的同款编辑器,为开发者提供了最好的开发体验
目前 LAPLACE Chat 提供了三种模版载入方式:
- 内置模版:由本站作者和第三方作者提供的内置免费模版,满足绝大多数的使用场景
- 远程模版:由第三方作者提供的远程模版,满足主播的客制化的需求
- 高级 CSS 编辑器(自定义 CSS 样式):由开发者或主播自行编写的 CSS 样式,满足任意定样式定制需求
云端载入(限内置模版)
当您开启本选项时,将会从本站内置的云端载入模版,该功能具有如下特性:
- 您不需要再在 OBS 中复制冗长的 CSS 样式,样式将始终保持最新状态
- 同时支持云端模版与自定义 CSS 样式,样式之间不冲突,自定义 CSS 样式将总是覆盖云端载入的样式
- 该选项可以用来解决一些主播不会配置样式的问题。以及由于弹幕机更新导致样式失效后无法及时更新样式的问题
- 解决个别第三方推流程序(例如哔哩哔哩直播姬)无法加载较长的自定义 CSS 的问题
该功能于 Apr 21, 2025 上线
远程模版
当您开启本选项时,将会从提供的 URL 中拉取可用的 CSS 样式。该特性可以方便开发者和设计师为 LAPLACE Chat 提供远程交付的 CSS 样式
测试模版:https://d3ksmgl05f2csh.cloudfront.net/assets/bubble-alt.css
该功能于 Apr 22, 2025 上线
高级 CSS 编辑器(自定义 CSS 样式)
最传统的模版定制方式,您可以在这里编写任意的 CSS 样式,然后将其复制到 OBS 中即可应用模版,该功能具有如下特性:
- 当您在配置器中载入了某个内置模版时,该模版的完整 CSS 代码将被载入到 CSS 编辑器中,您可以在此编辑此模版并提供实时的预览
- 如果您激活了「云端载入」功能时,此时 CSS 编辑器中的内容为参考样式,您可以删除其中大部分内容,仅保留您需要覆盖的 CSS 样式,然后将其复制到 OBS 的「自定义 CSS」中,即可覆盖云端模版的样式
模版优先级
LAPLACE Chat 的模版优先级按照下列顺序从低到高排列:
@layer template
- 云端载入(内置模版)@layer remote-css
- 远程模版@layer custom-css
- 高级 CSS 编辑器(自定义 CSS 样式)
当开发者按照上述规范编写层叠层样式时,自定义 CSS 将总是覆盖远程模版的样式;远程模版将总是覆盖云端载入的模版。三种载入方式可以同时存在
因此,利用此特性,您可以实现:
- 通过云端载入一款你喜欢的内置模版
- 在远程载入由他人基于此模版修改的二创样式
- 在自定义 CSS 中添加您自定义的样式
关于层叠层的详细用法,可参考 MDN 文档
开发者:如何交付远程模版
作为开发者,如果您需要远程交付模版,则需要满足如下几个条件:
- 您需要提供一个可用的 CSS 文件,并且可以稳定的通过 HTTPS 访问
- CSS 的内容与您直接在配置器中编辑的自定义 CSS 相同,不需要额外的格式
- 在样式中使用
@layer remote-css
层叠层,可更好的兼容模版的优先级 - CSS 文件尺寸小于 1024 KB(图片素材不计算在内)
- 放行所有来自 Cloudflare Workers 的 IP。通常来说不需要额外设置,如果您需要白名单放行,请参考 Cloudflare IP Ranges
- 放行所有来自
LAPLACE-Chat/* CSS-Preprocessor
的 User Agent 请求(例如LAPLACE-Chat/1.0.1 CSS-Preprocessor
)。通常来说不需要额外设置 - CSS 中的图片素材,需要可以通过 HTTPS 访问,并放行来自弹幕机的 CORS 请求
- 推荐使用境外的服务器进行存储,文件放在中国大陆可能反而会很慢
模版元数据
远程模版支持新特性「元数据」,您可以通过在 CSS 文件的最上方定义元数据为用户展示模版的详细信息,规范:
/*
@title 必填:模版标题
@author 必填:作者
@description 选填:模版描述
@updated 选填(建议填写):May 10, 2025, 1:39:30 AM PDT
@version 选填:版本,建议使用 semver。例如 1.0.0
@thumbnail 选填:预览图,建议尺寸 240×192px 的倍数。完整的 HTTPS 链接。例如 https://rsrc.laplace.cn/assets/chat-templates/thumbnails/laplace.png
*/
完整示例(顺序不受影响):
/*
@title 气泡样式(魔改)
@description 用来测试远程 CSS 的样式
@author LAPLACE Chat
@updated May 10, 2025, 7:02:13 AM PDT
@version 1.0.0
@thumbnail https://rsrc.laplace.cn/assets/chat-templates/thumbnails/laplace.png
*/
/* 引入 Google Fonts 字体,理论上国内可以直接访问 */
/* @import 不要嵌套在 @layer 层叠层内 */
@import url('https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,400;0,600;1,400;1,600&display=swap');
/* 模版本身样式,建议嵌套在 remote-css 层叠层内,可以更好的兼容模版优先级 */
@layer remote-css {
body { background-color: rgba(0, 0, 0, 0); }
/* 其他样式 */
...
}
只填写部分字段的示例:
/*
@title 气泡样式(魔改)
@author LAPLACE Chat
@updated May 10, 2025, 7:02:13 AM PDT
*/
@layer remote-css {
body { background-color: rgba(0, 0, 0, 0); }
/* 其他样式 */
...
}
该特性于 May 10, 2025 上线
鉴权
本站不会参与任何与鉴权、验证相关的流程,如果您提供的是付费模版,为了防止交付物被无授权使用,您可能需要自行实现鉴权以及访问统计等相关逻辑,可能的方案为:
- 为不同的客户提供不同的 URL 地址,例如:
https://example.com/templates/12345.css
https://example.com/templates/67890.css
- 为不同的客户提供不同的验证参数,例如:
https://example.com/templates/bubble.css?token=1234567890
https://example.com/templates/bubble.css?token=0987654321
- 只放行来自
LAPLACE-Chat/* CSS-Preprocessor
的 User Agent 请求 - 只放行来自 Cloudflare Workers 的 IP 的请求
请牢记
所有可以出现在屏幕上的内容,均可以通过技术手段复制、提取。请不要将链接的鉴权作为唯一的防盗版措施
缓存策略
- CSS 预处理器会将模版缓存至多 5 分钟,也就是说,最多每 5 分钟请求一次站源链接,如果您的模版有大量用户使用,可以考虑从站源额外增加缓存时间,以降低带宽压力,通常来说 1 万用户以下不需要过多考虑
- 客户端通过 ETag 来验证模版是否更新,默认 Cache-Control 头为 30 分钟
自动切换深色模式(OBS)
如果您的 OBS 中包含多个场景,例如一个浅色背景的场景,用于杂谈;一个深色背景的场景,用于游戏,那么通常的做法是在 OBS 中添加两个弹幕机源,一个设为浅色模式、一个深色。但这么做会有两个弊端:
- OBS 中相当于开了两个弹幕机,增加额外的资源占用,如果您有两个以上的场景,那么资源占用更多
- 在切换场景时,弹幕机的显示会不连贯、不够顺滑
因此,LAPLACE Chat 弹幕机引入了一个原创特性,可以直接调用 OBS 的 API,自动判断场景的类型,自动对弹幕机的颜色进行切换,作为用户,具体的使用方法为:
- 在浏览器源的「页面权限」一项中,将权限修改为「用户信息的读取权限(当前场景集合、转场)」
- 右键点击弹幕机源,选择「复制」
- 新建场景,或切换到其他场景中,在「来源」空白处右键,选择「粘贴(引用)」,此时两个场景中均会出现一个弹幕机,但是以类似指针的形式,都指向的同一个浏览器源
- 选定需要将弹幕机改为深色的场景,单击右键,然后重命名,在场景名称中添加
[dark]
字段。位置任意,推荐放在最后,例如 全屏游戏[dark]
如果您更擅长看视频而不是文字,可以参考下方的视频教程
作为开发者,您可以通过定义 [data-theme='dark']
与 [data-theme='light']
来实现对不同配色模式的强制切换:
@layer template {
[data-theme='light'] {
--mix-base: #000;
--mix-factor: 98%;
}
/* other styles */
...
}
样式跟随场景切换(OBS)
与上方的自动切换「深色模式」功能类似,上述方法可以拓展到自定义场景中
- 保持刚才设置的浏览器源权限
- 选定需要自定义的场景,单击右键,然后重命名,在场景名称中添加
[scene:name]
字段。name
为要添加的场景名,建议使用纯英文,不要带空格等特殊字符,例如全屏游戏 [dark] [scene:gaming]
- 完成设置后,再次切换场景,该场景下的弹幕机则会自动应用上全局的 CSS 样式
.scene-gaming
,此时可根据此样式重新定义当前场景下所有属性 - 如果您你是样式作者,你可以在「样式」标签页中输入「OBS 场景」,用来模拟 OBS 中自定义场景的情况
- 如果您更擅长看视频而不是文字,可以参考下方的视频教程
如果您更擅长看视频而不是文字,可以参考下方的视频教程
作为开发者,您可以通过定义 .scene-[name]
来实现一个模版中包含多个场景的样式:
@layer template {
/* 此样式只有在主播在当前场景名中添加 [scene:gaming] 时才会生效 */
.scene-gaming {
--mix-base: #000;
--mix-factor: 98%;
.event--message {
padding: calc(var(--1px) * 6) calc(var(--1px) * 10);
}
/* other styles */
...
}
/* 此样式只有在主播在当前场景名中添加 [scene:chit-chat] 时才会生效 */
.scene-chit-chat {
--mix-base: #000;
--mix-factor: 98%;
}
}
动态效果控制 reduced-motion
可以通过 reduced-motion
或 can-motion
条件类名来控制事件的动效,当事件速率大于特定值时,事件列表将应用全局的 reduced-motion
类名,否则应用 can-motion
类名。查看简约气泡(复刻)模版查看用例。控制台模式下为增强可读性,则总是应用 reduced-motion
类名
用例:
.event--message {
/* 只有当事件出现速率低于弹幕机内置的阈值时,对最后 n+2 条弹幕应用动画 */
.can-motion &:nth-last-child(-n + 2) {
animation: slideInFromBar1 ease-out forwards;
animation-duration: var(--animation-duration);
}
}
内置配色
LAPLACE Chat 基于 Kladewind 与 OKLCH 色彩空间提供了更加符合人眼视觉的 Scheme-based Color Auto Switching™(简称 SCAS)色盘,可基于当前系统配色自动微调整体明度(在本页切换配色方案可查看效果)
兼容性提醒
该配色方案仅支持 Chromium 版本高于 111 的 Google Chrome 浏览器或 OBS 版本高于 31 的推流软件
所有色盘兼容 Tailwind CSS 的配色命名方案。您可以使用下方的调色板快速查找和复制颜色变量
red
orange
amber
yellow
lime
green
emerald
teal
cyan
sky
blue
indigo
violet
purple
fuchsia
pink
rose
gray
参数
你可以通过下列参数微调 SCAS 色盘在不同场景下的表现:
--mix-base
:混合基色,默认值为#fff
--mix-factor
:混合因子,浅色模式下默认为100%
,深色模式下默认为75%
(即当前主色与混合基色所占比例中,主色占比 100%/75%)
使用示例
@layer remote-css {
[data-theme='dark'] {
--mix-base: #fffdbf;
--mix-factor: 50%;
}
.event {
--event-toast-bg-1: color-mix(in hsl, var(--color-red-900) 60%, transparent);
--event-toast-bg-2: color-mix(in hsl, var(--color-purple-900) 60%, transparent);
--event-toast-bg-3: color-mix(in hsl, var(--color-blue-900) 60%, transparent);
}
}
引导模版
作为模版作者,您可以参考下方的模版变量进行设计。请注意,该模版并没有包含全部变量,仅供参考
最后更新:Sep 20, 2024
/* 引导模版 by LAPLACE Chat */
/*
🛑本模版为引导模版,包含大多数的 CSS 变量定义,您可在当前模版的基础上通过修改 CSS 对样式进行自定义
LAPLACE Chat 的编辑器为 VS Code 同款编辑器,支持颜色可视化取色,快捷键也与 VS Code 一致,可直接在编辑器中设计样式
编辑的内容会自动保存在本地,页面刷新后可自动恢复
被注释掉的属性可按 ctrl - /(Windows)或者 command - /(macOS)取消注释
*/
/* 引入 Google Fonts 字体,理论上国内可以直接访问 */
/* 更多字形可通过访问 https://fonts.google.com/ 进行挑选 */
@import url('https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,400;0,600;1,400;1,600&display=swap');
/* 请根据实际的载入场景选择使用 remote-css 或 custom-css 层叠层 */
@layer custom-css {
/* 创建弹幕专用变量 */
.event {
/* 以下为平台内置变量 */
/* 应用全局自定义字体 */
/* --font-sans 为 LAPLACE Chat 内置变量,可调用非衬线字体 */
--event-font-family: 'Jost', var(--font-sans);
/* 弹幕文本颜色 */
/* --event-message-text: red; */
/* 也可以套用内置变量,该变量会自动根据深色模式自动调整颜色 */
/* --event-message-color: var(--text-color); */
/* 在这里重新定义普通弹幕、总督、提督、舰长用户名的文本颜色 */
--event-username-text-0: #037456;
--event-username-text-1: rgb(242, 118, 109);
--event-username-text-2: rgb(185, 81, 220);
--event-username-text-3: rgb(67, 114, 255);
/* 弹幕颜色变量 */
--event-danmaku-text: rgb(0, 0, 0);
--event-danmaku-text-0: rgb(30, 101, 58);
--event-danmaku-text-1: rgb(182, 10, 39);
--event-danmaku-text-2: rgb(123, 16, 111);
--event-danmaku-text-3: rgb(23, 70, 158);
--event-danmaku-bg-0: rgba(114, 255, 140, 0.193);
--event-danmaku-bg-1: rgba(254, 60, 96, 0.13);
--event-danmaku-bg-2: rgba(248, 97, 246, 0.138);
--event-danmaku-bg-3: rgba(0, 132, 255, 0.175);
--event-danmaku-current-rank-text: rgb(0, 0, 0);
--event-danmaku-current-rank-text-1: rgb(96, 62, 3);
--event-danmaku-current-rank-text-2: rgb(63, 70, 87);
--event-danmaku-current-rank-text-3: rgb(101, 54, 20);
--event-danmaku-current-rank-bg-1: rgb(255, 207, 50);
--event-danmaku-current-rank-bg-2: rgb(203, 203, 207);
--event-danmaku-current-rank-bg-3: rgb(233, 180, 147);
--event-danmaku-mod-text: rgb(102, 105, 185);
--event-danmaku-streamer-text: rgb(191, 120, 192);
/* 醒目留言颜色变量 */
--event-superchat-top-text: #000000;
--event-superchat-top-text-1: rgb(8, 22, 146);
--event-superchat-top-text-2: rgb(6, 81, 127);
--event-superchat-top-text-3: rgb(154, 111, 19);
--event-superchat-top-text-4: rgb(164, 82, 31);
--event-superchat-top-text-5: rgb(146, 17, 8);
--event-superchat-top-text-6: rgb(127, 9, 46);
--event-superchat-top-bg-1: rgba(16, 67, 255, 0.368);
--event-superchat-top-bg-2: rgba(16, 167, 255, 0.368);
--event-superchat-top-bg-3: rgba(255, 235, 16, 0.368);
--event-superchat-top-bg-4: rgba(255, 124, 16, 0.368);
--event-superchat-top-bg-5: rgba(255, 40, 16, 0.368);
--event-superchat-top-bg-6: rgba(255, 16, 64, 0.368);
--event-superchat-message-text: rgb(255, 255, 255);
--event-superchat-message-text-1: rgb(225, 234, 255);
--event-superchat-message-text-2: rgb(225, 252, 255);
--event-superchat-message-text-3: rgb(255, 251, 225);
--event-superchat-message-text-4: rgb(255, 237, 225);
--event-superchat-message-text-5: rgb(255, 226, 225);
--event-superchat-message-text-6: rgb(255, 221, 229);
--event-superchat-bg: transparent;
--event-superchat-bg-1: rgb(48, 42, 209);
--event-superchat-bg-2: rgb(32, 137, 194);
--event-superchat-bg-3: rgb(221, 159, 36);
--event-superchat-bg-4: rgb(209, 117, 42);
--event-superchat-bg-5: rgb(209, 59, 42);
--event-superchat-bg-6: rgb(167, 16, 16);
/* 礼物颜色变量 */
--event-gift-text: rgb(0, 0, 0);
--event-gift-text-1: rgb(239, 242, 255);
--event-gift-text-2: rgb(220, 255, 233);
--event-gift-text-3: rgb(99, 69, 0);
--event-gift-text-4: rgb(255, 247, 241);
--event-gift-text-5: rgb(255, 243, 243);
--event-gift-text-6: rgb(255, 226, 230);
--event-gift-bg-1: rgb(55, 126, 224);
--event-gift-bg-2: rgb(82, 183, 67);
--event-gift-bg-3: rgb(255, 208, 67);
--event-gift-bg-4: rgb(255, 145, 41);
--event-gift-bg-5: rgb(242, 68, 68);
--event-gift-bg-6: rgb(160, 0, 51);
--event-gift-normal-text-1: rgb(29, 82, 155);
--event-gift-normal-text-2: rgb(44, 141, 29);
--event-gift-normal-text-3: rgb(180, 140, 21);
--event-gift-normal-text-4: rgb(231, 125, 25);
--event-gift-normal-text-5: rgb(181, 34, 34);
--event-gift-normal-text-6: rgb(150, 9, 54);
--event-gift-normal-bg-1: transparent;
--event-gift-normal-bg-2: transparent;
--event-gift-normal-bg-3: transparent;
--event-gift-normal-bg-4: transparent;
--event-gift-normal-bg-5: transparent;
--event-gift-normal-bg-6: transparent;
/* 舰长颜色变量 */
--event-toast-text: rgb(0, 0, 0);
--event-toast-text-1: rgb(140, 0, 0);
--event-toast-text-2: rgb(118, 18, 152);
--event-toast-text-3: rgb(0, 56, 146);
--event-toast-bg-1: rgb(255, 185, 187);
--event-toast-bg-2: rgb(250, 187, 255);
--event-toast-bg-3: rgb(192, 216, 255);
/* MVP(守护圣法师、etc)颜色变量 */
--event-mvp-text: rgb(0, 0, 0);
--event-mvp-text-1: rgb(114, 79, 47);
--event-mvp-text-2: rgb(114, 79, 47);
--event-mvp-text-3: rgb(114, 79, 47);
--event-mvp-text-4: rgb(114, 79, 47);
--event-mvp-text-5: rgb(114, 79, 47);
--event-mvp-text-6: rgb(114, 79, 47);
--event-mvp-bg-1: rgb(229, 211, 183);
--event-mvp-bg-2: rgb(229, 211, 183);
--event-mvp-bg-3: rgb(229, 211, 183);
--event-mvp-bg-4: rgb(229, 211, 183);
--event-mvp-bg-5: rgb(229, 211, 183);
--event-mvp-bg-6: rgb(229, 211, 183);
/* 互动颜色变量 */
--event-interaction-text-enter: rgb(127, 137, 159);
--event-interaction-text-follow: rgb(219, 113, 7);
--event-interaction-text-share: rgb(174, 85, 207);
--event-interaction-text-follow-special: rgb(217, 50, 50);
--event-interaction-text-follow-mutual: rgb(47, 142, 219);
/* 系统颜色变量 */
--event-system-text: rgba(35, 34, 37, 0.553);
/* 禁言颜色变量 */
--event-user-block-text: #fff;
--event-user-block-bg: rgb(255, 0, 0);
}
/* 弹幕类型变量 */
.event--message {
/* --avatar-size: 18px; */
}
/* 总督变量 */
.event.guard-level--1 {
}
/* 提督变量 */
.event.guard-level--2 {
}
/* 舰长变量 */
.event.guard-level--3 {
}
/* 弹幕事件样式 */
.event--message {
}
/* 弹幕事件中的消息样式 */
.event--message .message {
}
/* 粉丝勋章样式 */
.event--message .fans-medal {
}
/* 粉丝勋章名称样式 */
.event--message .fans-medal-content {
}
/* 粉丝勋章等级样式 */
.event--message .fans-medal-level {
}
/* 修改「榜1」图标 */
/* 变量定义可从 https://master--60f5c0ae4a7e3f003ba05641.chromatic.com/ 查看 */
.event--message .current-rank {
}
/* 修改房管图标 */
.event--message .mod-badge {
}
/* 舰长事件样式 */
/*
.event-show-as--normal 将排除置顶礼物条
.event-show-as--sticky 用于置顶礼物条
*/
.event--toast.event-show-as--normal {
}
/* 礼物事件样式 */
/*
.event-size--highlight 将排除非高亮礼物事件
.event-size--normal 用于非高亮事件
*/
.event--gift.event-show-as--normal.event-size--highlight {
}
/* SC 样式 */
/* SC 颜色分为上下两个部分,因此需要单独定义背景 */
.event--superchat.event-show-as--normal {
}
/* SC 上方样式 */
.event--superchat.event-show-as--normal .top {
}
/* SC 下方正文样式 */
.event--superchat.event-show-as--normal .message {
}
/* 礼物/SC文本颜色变量 */
/*
此处可使用 .event-superchat-rank--[n] 和 .event-gift-rank--[n] 分别定义样式,
也可以像我这样使用 .event-price-rank--[n] 统一定义样式
*/
.event.event-price-rank--1 {
}
.event.event-price-rank--2 {
}
.event.event-price-rank--3 {
}
.event.event-price-rank--4 {
}
.event.event-price-rank--5 {
}
.event.event-price-rank--6 {
}
}