惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Security Latest
Security Latest
P
Palo Alto Networks Blog
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
T
Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Latest news
Latest news
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
J
Java Code Geeks
P
Privacy International News Feed
阮一峰的网络日志
阮一峰的网络日志
S
Schneier on Security
博客园 - 聂微东
Project Zero
Project Zero
美团技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Scott Helme
Scott Helme
I
Intezer
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hacker News: Front Page
S
Security @ Cisco Blogs
博客园 - 司徒正美
O
OpenAI News
Last Week in AI
Last Week in AI
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
SecWiki News
SecWiki News
月光博客
月光博客
S
Security Affairs
The GitHub Blog
The GitHub Blog
P
Privacy & Cybersecurity Law Blog
S
Secure Thoughts
V
V2EX
S
Securelist
F
Fortinet All Blogs
W
WeLiveSecurity
D
Docker
博客园 - 三生石上(FineUI控件)
Simon Willison's Weblog
Simon Willison's Weblog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
V
Visual Studio Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Webroot Blog
Webroot Blog
Engineering at Meta
Engineering at Meta

qlAD 的技术笔记

2026 年 6 月 7 日 -- 我有社交恐惧症,恐惧外面到处雷电风雨声(大学生活记录) 手把手带你实现哈希表(C/C++ 数据结构) 手把手带你实现图结构(C/C++ 数据结构) 手把手带你实现二叉树(C/C++ 数据结构) 手把手带你实现栈和队列(C/C++ 数据结构) 手把手带你实现单/双链表(C/C++ 数据结构) 手把手带你实现动态数组(C/C++ 数据结构) 2026 年 1 月 2 日 -- 我不怕冷,因为我内心炽热 【2025 年度总结】(大学生活记录) 2025 年 12 月 2 日 -- 省电模式:大一 100 天耗电日志(大学生活记录) 蓝桥杯备赛第一期 —— 枚举与模拟 2025 年 11 月 3 日 -- 用爱发电、大爱无私(大学生活记录) 使用循环嵌套输出规则图形找规律讲解(嵌套循环-图形输出) 2025 年 10 月 1 日 -- 二字开头第一年的生日记录及感悟随笔(大学生活记录) Python 初级 04 -- 目前为止 Python 中你们做题可能会遇到的问题以及七七八八 2025 年 9 月 24 日 -- 开学后的第一课及军训汇演(大学生活记录) Python 初级 03 -- 程序设计的三种结构之选择结构和循环结构 Python 初级 02 -- 基础的数据类型和输入输出 2025 年 9 月 17 日 -- 大连 2025 国际大体联足球世界杯(大学生活记录) Python 初级 01 -- 初识编程、理解计算机语言及程序运行方式 适合大一新生学习编程的前一课 -- 编程先导(编程的本质) 2025 年 9 月 12 日 -- 三天军训感受以及一些七七八八(大学生活记录) 2025 年 9 月 9 日 -- 体检、军训前的准备(大学生活记录) 适合大一新生的计算机基础知识 -- 个人认为足够版 2025 年 9 月 7 日 -- 既来之、则安之(大学生活记录) C++ 程序的内存布局 —— 代码区、全局/静态区、栈区和堆区 联想小新 pro 16 2025 开箱记录:跳过联网、office 激活、更换 win 11 专业版 R 语言中的数学函数 计算机软件著作权申请过程记录 从聚类到回归:用 Python 解析鸢尾花数据集的完整数据科学流程 条件概率、全概率与贝叶斯公式 —— 一篇文章带你死磕概率公式 高中化学物质反应规则表 —— 方程式之间也有规律可循 集合元素性质、关系、子集公式、基本运算 —— 一篇文章带你全方面死磕集合 如何为你的项目选择合适的许可证 -- 全方位指南 解释 3:1 和 9:3:3:1 的详细来源 —— 建立减数分裂与孟德尔遗传学定律之间的联系 重新设置磁盘分区以及 Btrfs 子卷(subvolume)布局的无损方案 零基础实战:用 Docker 启动 dockermailserver 绕过 25 端口封锁搭建个人邮箱服务器 基于 GitHub Actions + OSS 的自托管 APT 仓库全面指南 如何在安装 Debian 时配置 Btrfs 子卷 | 详细分步指南 一个合格的个人网站站长应该知道哪些事? CSS 基础入门教程 —— 选择器、样式声明 HTML 基础入门 —— 基本结构和语法 给博客添加一个文章数据统计的页面 Git 学习笔记(命令备忘表) Anki 牌组选项详细解释与设置 手动编译带有 KernelSU 的 OnePlus 6 内核 安卓类原生系统补全计划 —— PixelExperience(一加 OnePlus) 如何使用 use-sound 为 React 应用添加声音效果 标准化项目的 GitHub Flow 工作流 如何搭建设计自己的博客网站? 配置 GitHub Actions 实现自动化提交百度收录 第00期 | 环境搭建 & 递归 (一) | 基本数列递归 逐字符讲解 C 语言 HelloWorld 程序 2023 年回顾 🤟 Anki:记忆神器,助你高效学习 Gentoo 学习笔记 美化你的 PixelExperience OS Markdown 语法指南 搭建 OneDrive 目录索引 为什么用 65 表示大写字母 A
使用安知鱼主题同款的 Twikoo 评论组件
qlAD · 2024-10-05 · via qlAD 的技术笔记

cover

一、私有部署(Docker)

私有部署涉及终端操作、申请证书、配置反向代理或负载均衡等高级操作,如果对这些不太了解,建议优先选择其他方式部署。

1、Docker Compose

version: "3.8"

services:
  twikoo:
    image: imaegoo/twikoo
    container_name: twikoo
    restart: unless-stopped
    ports:
      - 8888:8080
    environment:
      TWIKOO_THROTTLE: 1000
    volumes:
      - twikoo_data:/app/data

volumes:
  twikoo_data:
    external: true

在 8888:8080 中,8888 表示宿主机的端口,8080 表示容器内的端口。这意味着宿主机的 8888 将映射到容器内的 8080 端口,以便外部通过 ip:8888 访问容器内的服务。

为了保证数据不丢失,这里使用了外部 volumes,默认在 /var/lib/docker/volumes/twikoo_data。这允许容器重新创建或更新时,数据仍然保留在宿主机上,而不会被删除或覆盖。

使用 docker compose 运行来创建容器

通过浏览器访问 ip:8888 查询 Twikoo 是否运行成功。

Twikoo 运行成功示例

2、评论数据的处理

Twikoo 的数据格式为 json 文件,文件位置在容器中的 data 目录,因为使用了 volumes 所以可以在宿主机上找到。

单条评论数据示例:

{
  "_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "nick": "qlAD",
  "mail": "qlad_adgk@163.com",
  "mailMd5": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "link": "www.qladgk.com",
  "ua": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36",
  "ip": "12.13.14.15",
  "master": true,
  "url": "/links",
  "href": "https://qladgk.com/links",
  "comment": "<p>已添加,预计今日更新</p>\n",
  "pid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "rid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "isSpam": false,
  "created": 1111111111111,
  "updated": 1111111111111,
  "ipRegion": "陕西省 XX市 电信",
  "meta": { "revision": 0, "created": 1111111111111, "version": 0 },
  "$loki": 20
}

你可以对原 json 数据文件进行修改、导入、导出。

或者使用 Twikoo 的后台管理面板进行数据的操作。

Twikoo 管理面板

3、后续处理步骤

配置前置代理实现 HTTPS 访问(可以用 Nginx、负载均衡或 Cloudflare 等)

二、样式魔改

可以直接去看安知鱼主题的 GitHub 仓库,里面有 Twikoo 的 styl 文件

CSS 的版本如下:

/* 颜色 */
:root {
  --twikoo-theme-op: #4259ef23;
  --twikoo-white: #fff;
  --twikoo-main: var(--twikoo-theme);
  --twikoo-shadow-black: 0 0 12px 4px rgba(0, 0, 0, 0.05);
  --twikoo-shadow-border: 0 8px 16px -4px #2c2d300c;
  --style-border: 1px solid var(--twikoo-card-border);
  --style-border-hover: 2px solid var(--twikoo-main);
  --style-border-dashed: 1px dashed var(--twikoo-theme-op);
  --style-border-avatar: 4px solid var(--twikoo-background);
  --style-border-always: 2px solid var(--twikoo-card-border);
}

.light {
  --twikoo-theme: #a78bfa;
  --twikoo-theme-op: #a78bfa23;
  --twikoo-green: #57bd6a;
  --twikoo-fontcolor: #363636;
  --twikoo-background: #f7f9fe;
  --twikoo-maskbg: rgba(255, 255, 255, 0.6);
  --twikoo-lighttext: var(--twikoo-main);
  --twikoo-secondtext: rgba(60, 60, 67, 0.6);
  --twikoo-secondbg: #edf0f7;
  --twikoo-card-bg: #fff;
  --twikoo-shadow-lightblack: 0 5px 12px -5px rgba(102, 68, 68, 0);
  --twikoo-card-border: #c0c6d8;
}

.dark {
  --twikoo-theme: #a78bfa;
  --twikoo-theme-op: #a78bfa23;
  --twikoo-green: #57bd6a;
  --twikoo-fontcolor: #f7f7fa;
  --twikoo-background: #18171d;
  --twikoo-maskbg: rgba(0, 0, 0, 0.6);
  --twikoo-lighttext: #f2b94b;
  --twikoo-secondtext: #a1a2b8;
  --twikoo-secondbg: #30343f;
  --twikoo-card-bg: #1d1b26;
  --twikoo-shadow-lightblack: 0 5px 12px -5px rgba(102, 68, 68, 0);
  --twikoo-card-border: #42444a;
}

.OwO .OwO-body {
  min-width: 31.25rem;
}
.twikoo svg {
  color: var(--twikoo-fontcolor);
}
/* 评论区表情放大 */
@keyframes owoIn {
  0% {
    transform: translate(0, -95%);
    opacity: 0;
  }
  100% {
    transform: translate(0, -112%);
    opacity: 1;
  }
}

#owo-big {
  position: fixed;
  align-items: center;
  background-color: rgb(255, 255, 255);
  border: 1px #aaa solid;
  border-radius: 10px;
  z-index: 9999;
  display: none;
  transform: translate(0, -112%);
  overflow: hidden;
  animation: owoIn 0.3s cubic-bezier(0.42, 0, 0.3, 1.11);
}
#owo-big img {
  width: 100%;
}

.tk-expand {
  width: 100%;
  cursor: pointer;
  padding: 0.75em;
  text-align: center;
  transition: all 0.5s;
  border: var(--style-border);
  box-shadow: 0 8px 16px -4px #2c2d300c;
  border-radius: 50px;
  letter-spacing: 5px;
  background-color: var(--twikoo-card-bg);
}

#twikoo .tk-comments > .tk-submit {
  overflow: visible !important;
}
#twikoo .tk-comments .OwO .OwO-body {
  border: var(--style-border-always) !important;
  border-radius: 8px !important;
  overflow: hidden;
  background-color: var(--twikoo-maskbg) !important;
  backdrop-filter: saturate(180%) blur(10px);
  cursor: auto;
  top: 2.1em !important;
  transform: translateZ(0);
  animation: 0.3s ease 0.1s 1 normal both running donate_effcet;
}
#twikoo .tk-comments .OwO .OwO-body .OwO-items-show {
  margin: 12px 8px;
}
#twikoo
  .tk-comments
  button.el-button.tk-cancel.el-button--default.el-button--small {
  background: var(--twikoo-secondbg);
  border-radius: 8px;
  color: var(--twikoo-fontcolor);
}
#twikoo
  .tk-comments
  button.el-button.tk-cancel.el-button--default.el-button--small:hover {
  background: var(--twikoo-lighttext);
  color: var(--twikoo-white);
}
#twikoo .tk-comments a.tk-submit-action-icon.__markdown {
  display: none;
}
#twikoo .tk-comments > div.tk-submit > div.tk-row.actions > a {
  display: none;
}
#twikoo .tk-comments .el-button.tk-preview {
  display: none;
}
#twikoo .tk-comments .el-button--primary.is-disabled,
#twikoo .tk-comments .el-button--primary.is-disabled:active,
#twikoo .tk-comments .el-button--primary.is-disabled:focus,
#twikoo .tk-comments .el-button--primary.is-disabled:hover {
  opacity: 0.2;
}
#twikoo .tk-comments .el-button--primary {
  border-color: var(--twikoo-fontcolor);
  color: var(--twikoo-card-bg);
  border-radius: 12px;
  box-shadow: var(--twikoo-shadow-black);
  transition: 0.3s;
  width: 6.25rem;
  position: absolute;
  top: -43px;
  right: 0;
  margin-left: 0.5rem !important;
  height: 32px;
}
#twikoo .tk-comments .tk-input .el-textarea__inner {
  min-height: 130px !important;
  border-radius: 15px;
  display: block;
  resize: vertical;
  padding: 16px 16px 40px 16px;
  line-height: 1.5;
  box-sizing: border-box;
  width: 100%;
  font-size: inherit;
  color: var(--twikoo-fontcolor);
  background-color: var(--twikoo-secondbg);
  border: var(--style-border-always);
  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
}

#twikoo .tk-comments .el-input__inner {
  background: var(--twikoo-secondbg) !important;
  border: none !important;
  color: var(--twikoo-fontcolor) !important;
  padding-left: 8px;
}
#twikoo .tk-comments .el-input__inner:focus {
  border: none;
}
#twikoo .tk-comments .el-input-group__append,
#twikoo .tk-comments .el-input-group__prepend {
  background-color: var(--twikoo-card-bg);
  color: var(--twikoo-fontcolor);
  border-color: var(--twikoo-card-border);
  border: none;
  font-weight: 700;
}
#twikoo .tk-comments .el-input-group--prepend .el-input__inner,
#twikoo .tk-comments .el-input-group__append {
  border-radius: 0 10px 10px 0;
}
#twikoo .tk-comments .el-input--small .el-input__inner {
  padding: 8px;
  padding-left: 16px;
}
#twikoo .tk-comments .el-input-group--prepend .el-input__inner,
#twikoo .tk-comments .el-input-group__append {
  border-left-width: 0 !important;
}
#twikoo .tk-comments .tk-meta-input {
  position: relative;
  margin-top: 8px;
  width: calc(100% - 6.875rem);
}
#twikoo
  .tk-comments
  .tk-meta-input
  .el-input.el-input--small.el-input-group.el-input-group--prepend {
  border-radius: 12px;
  background: var(--twikoo-secondbg);
  border: var(--style-border-always);
}
#twikoo .tk-comments .tk-meta-input .el-input .el-input-group__prepend {
  user-select: none;
  border-radius: 12px 0 0 12px;
}
#twikoo
  .tk-comments
  .tk-meta-input
  .el-input--small.el-input-group.el-input-group--prepend:focus-within {
  border: var(--style-border-hover);
}
#twikoo .tk-comments .tk-row .tk-avatar {
  display: none;
}
#twikoo .tk-comments .tk-row .tk-col {
  flex-direction: column-reverse;
}
#twikoo .tk-comments .tk-row.actions {
  margin-bottom: 0;
  margin-left: 0;
  margin-top: 0;
  justify-content: space-around;
}
#twikoo .tk-comments .tk-admin {
  backdrop-filter: blur(5px);
}
#twikoo .tk-comments .el-button {
  background-color: var(--twikoo-fontcolor);
  border: 0 solid var(--twikoo-main);
  color: var(--twikoo-background);
}
#twikoo .tk-comments .tk-tag-green {
  background-color: var(--twikoo-main);
  border: none;
  border-radius: 4px;
  color: var(--twikoo-white);
}
#twikoo .tk-comments .tk-action-icon {
  color: var(--twikoo-main);
  cursor: pointer;
}
#twikoo .tk-comments .tk-icon.__comments {
  color: var(--twikoo-main);
}
#twikoo .tk-comments .tk-actions a {
  cursor: pointer;
}
#twikoo .tk-comments .tk-nick {
  line-height: 40px;
}
#twikoo .tk-comments .tk-extras {
  margin-top: 0.5rem;
  padding-bottom: 0.5rem;
}
#twikoo .tk-comments .tk-expand:hover {
  color: #fff;
  background-color: var(--twikoo-main);
  border: var(--style-border-none);
}

#twikoo .tk-comments .tk-content p {
  margin: 0;
}
#twikoo .tk-comments .tk-admin-config-input .el-input__inner {
  background: transparent !important;
}
#twikoo pre code {
  background: none;
}
#twikoo code {
  padding: 2px 4px;
  background: var(--twikoo-secondbg);
  color: #f47466;
}
#twikoo .tk-comment .tk-submit .tk-avatar,
#twikoo .tk-replies .tk-avatar {
  height: 2.5rem !important;
  width: 2.5rem !important;
}
#twikoo .tk-comment pre {
  background: #272822;
  padding: 1em;
  margin: 0.5em 0;
  overflow: auto;
  border-radius: 0.3em;
}

@media screen and (max-width: 768px) {
  #twikoo .tk-comments-container .tk-comment {
    padding: 1rem;
    border: var(--style-border-always);
    box-shadow: var(--twikoo-shadow-border);
    background: var(--twikoo-card-bg);
  }
  #twikoo .tk-replies .tk-comment {
    border: none;
  }
}

#twikoo .tk-avatar {
  border-radius: 50px;
}
#twikoo .tk-avatar .tk-avatar-img {
  height: 2.5rem !important;
}

#twikoo .tk-replies {
  max-height: 10rem !important;
}
#twikoo .tk-replies.tk-replies-expand {
  max-height: none !important;
}
#twikoo .tk-replies .tk-comment {
  border-top: var(--style-border-dashed);
  border-radius: 12px;
  padding: 1rem 0px 0px;
  margin-top: 0;
  transition: all 0.3s ease 0s;
}
#twikoo .tk-replies .tk-content span:first-child:not(.token) {
  font-size: 0.75rem;
  color: var(--twikoo-secondtext);
}

[data-theme="dark"] #owo-big {
  background-color: #4a4a4a;
}
.tk-comments-container .tk-submit {
  opacity: 1;
  height: auto;
  overflow: visible;
}
/* 输入提示 */
/* 设置文字内容 :nth-child(1)的作用是选择第几个 */
.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(
    1
  ):before {
  content: "输入QQ号会自动获取昵称和头像🐧";
}

.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(
    2
  ):before {
  content: "收到回复将会发送到您的邮箱📧";
}

.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(
    3
  ):before {
  content: "可以通过昵称访问您的网站🔗";
}

/* 当用户点击输入框时显示 */
.el-input.el-input--small.el-input-group.el-input-group--prepend:focus-within::before {
  display: block;
  animation: commonTipsIn 0.3s;
  z-index: 2;
}

.el-input.el-input--small.el-input-group.el-input-group--prepend:focus-within::after {
  display: block;
  animation: commonTriangleIn 0.3s;
}

/* 主内容区 */
.el-input.el-input--small.el-input-group.el-input-group--prepend::before {
  display: none;
  position: absolute;
  top: -60px;
  white-space: nowrap;
  border-radius: 10px;
  left: 50%;
  transform: translate(-50%);
  padding: 14px 18px;
  background: #444;
  color: #fff;
  z-index: 100;
}

/* 小角标 */
.el-input.el-input--small.el-input-group.el-input-group--prepend::after {
  display: none;
  content: "";
  position: absolute;
  border: 12px solid transparent;
  border-top-color: #444;
  left: 50%;
  transform: translate(-50%, -46px);
}

/* 评论框 */
.vwrap {
  box-shadow: 2px 2px 5px #bbb;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 8px;
  padding: 30px;
  margin: 30px 0px 30px 0px;
}

/* 设置评论框 */
.vcard {
  box-shadow: 2px 2px 5px #bbb;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 8px;
  padding: 30px;
  margin: 30px 0px 0px 0px;
}

#twikoo .tk-extra {
  background: var(--twikoo-card-bg);
  border: var(--style-border-always);
  padding: 4px 8px;
  border-radius: 8px;
  margin-right: 4px;
  color: var(--twikoo-secondtext);
  margin-top: 6px;
  font-size: 0.8rem;
}
#twikoo .tk-extra-text {
  font-size: 0.75rem;
}
#twikoo .tk-replies .tk-content {
  font-size: 0.9rem;
}
#twikoo .tk-content {
  margin-top: 0;
}
.tk-content span a:not([data-fancybox="gallery"]) {
  font-weight: 500;
  border-bottom: solid 2px var(--twikoo-lighttext);
  color: var(--twikoo-fontcolor);
  padding: 0 0.2em;
  text-decoration: none;
}
.tk-content span a:not([data-fancybox="gallery"]):hover {
  color: var(--twikoo-white);
  background-color: var(--twikoo-theme);
  border-radius: 4px;
}
.tk-main .tk-content span > a {
  border-bottom: none;
}
#post-comment .comment-head {
  font-size: 0.8em !important;
  margin-bottom: 0.5rem;
}

@keyframes commonTipsIn {
  0% {
    top: -50px;
    opacity: 0;
  }
  100% {
    top: -60px;
    opacity: 1;
  }
}

@keyframes commonTriangleIn {
  0% {
    transform: translate(-50%, -36px);
    opacity: 0;
  }
  100% {
    transform: translate(-50%, -46px);
    opacity: 1;
  }
}
@keyframes donate_effcet {
  0% {
    opacity: 0;
    transform: translateY(-20px);
  }
  100% {
    opacity: 1;
    filter: none;
    transform: translateY(0);
  }
}

#body-wrap.page .el-input__inner {
  background: var(--twikoo-card-bg);
  box-shadow: var(--twikoo-shadow-border);
  color: var(--twikoo-fontcolor);
}
#body-wrap.page .tk-admin-config .el-input__inner {
  color: currentColor;
}

#twikoo.twikoo .el-input__inner:focus,
#twikoo.twikoo .el-textarea__inner:focus {
  /* border-color: var(--twikoo-main); */
}

.tk-comments-container > .tk-comment {
  margin-top: 0 !important;
  margin-bottom: 1rem !important;
  transition: 0.3s;
  border-radius: 12px;
  padding: 0;
  padding-top: 1rem;
  border: none;
  border-top: var(--style-border-dashed);
}

#post-comment .comment-tips {
  background-color: rgba(103, 194, 58, 0.13);
  border: var(--style-border-always);
  border-color: var(--twikoo-green);
  color: var(--twikoo-green);
  border-radius: 8px;
  padding: 8px 12px;
  margin-top: 0.5rem;
  display: none;
  width: 100%;
}

#post-comment .comment-tips.show {
  display: flex;
}

#page .tk-comments-container > .tk-comment {
  background: var(--twikoo-card-bg);
  padding: 1rem;
  padding-bottom: 1rem;
  border: var(--style-border);
  border-top: var(--style-border);
  box-shadow: var(--twikoo-shadow-border);
}
@media (prefers-reduced-motion: no-preference) {
  #page .tk-comments-container > .tk-comment {
    animation: animate-in-and-out 1s linear forwards;
    animation-timeline: view();
  }
  #page .tk-comments-container > .tk-comment:has(.OwO-open) {
    z-index: 1;
  }
}

.tk-content {
  margin-top: 0.5rem;
  overflow: auto;
  max-height: 500px;
}

.tk-comments .tk-row-actions-start {
  position: absolute;
  top: -84px;
  left: 17px;
}

@media screen and (max-width: 768px) {
  .OwO .OwO-body {
    min-width: 260px;
  }
  .tk-comments .tk-row-actions-start {
    top: -176px;
  }
  #twikoo .tk-comments .tk-submit .el-button--primary {
    height: 122px;
    top: -126px;
  }
  #twikoo .el-textarea__inner {
    background: var(--twikoo-card-bg) !important;
    overflow: hidden;
    resize: none !important;
  }

  .tk-comments button.el-button.tk-preview.el-button--default.el-button--small {
    display: none;
  }
  .tk-comments .tk-main .tk-submit .tk-row.actions {
    justify-content: center;
  }
  .tk-comments button.el-button.tk-send,
  .tk-comments button.el-button.tk-cancel {
    width: 100%;
  }
  .tk-comments .tk-row-actions-start {
    position: absolute;
  }
}

.OwO .OwO-body .OwO-items .OwO-item:hover {
  box-shadow: var(--twikoo-shadow-lightblack) !important;
  border-radius: 8px;
}

三、使用组件(前端部署)

Twikoo 支持的博客主题:https://twikoo.js.org/frontend.html

如果你的博客不支持 Twikoo 则使用 CDN 引入,反之查看你博客对应的官方文档

<div id="tcomment"></div>
<script src="https://cdn.jsdelivr.net/npm/twikoo@1.6.39/dist/twikoo.all.min.js"></script>
<script>
  twikoo.init({
    envId: "您的环境id", // 腾讯云环境填 envId;Vercel 环境填地址(https://xxx.vercel.app)
    el: "#tcomment", // 容器元素
    // region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,腾讯云环境填 ap-shanghai 或 ap-guangzhou;Vercel 环境不填
    // path: location.pathname, // 用于区分不同文章的自定义 js 路径,如果您的文章路径不是 location.pathname,需传此参数
    // lang: 'zh-CN', // 用于手动设定评论区语言,支持的语言列表 https://github.com/twikoojs/twikoo/blob/main/src/client/utils/i18n/index.js
  });
</script>