Subspace Institute

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 的模版优先级按照下列顺序从低到高排列:

  1. @layer template - 云端载入(内置模版)
  2. @layer remote-css - 远程模版
  3. @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-Preprocesssor 的 User Agent 请求(例如 LAPLACE-Chat/1.0 CSS-Preprocesssor)。通常来说不需要额外设置
  • 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-Preprocesssor 的 User Agent 请求
  • 只放行来自 Cloudflare Workers 的 IP 的请求

请牢记

所有可以出现在屏幕上的内容,均可以通过技术手段复制、提取。请不要将链接的鉴权作为唯一的防盗版措施

缓存策略

  • CSS 预处理器会将模版缓存至多 5 分钟,也就是说,最多每 5 分钟请求一次站源链接,如果您的模版有大量用户使用,可以考虑从站源额外增加缓存时间,以降低带宽压力,通常来说 1 万用户以下不需要过多考虑
  • 客户端通过 ETag 来验证模版是否更新,默认 Cache-Control 头为 30 分钟

内置配色

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 {
  }
}