“写笔记”支持四种格式——Word 文档、Excel 表格、Markdown、纯文本,起稿或二次编辑时都能随时切换,同一篇笔记想用哪种形态来记,都由你说了算。
md、txt、csv、json 这类纯文本则原样载入,不做多余加工。拿一张现成的表倒进来、改几笔、再导出去,等于白用一台免费的格式转换器。
要带走就在右上角点“下载”,可导出 PDF、Word、Markdown、Excel、TXT 等格式;列表卡片“⋯”菜单里,也有同样的下载入口。
在“工具”页点“+ 上传工具”即可发布:填好名称与链接,再用 Markdown 把使用方法写清楚——能解决什么问题、怎么装、怎么用,比堆介绍实在。
要分发安装包就一并上传压缩包(ZIP、RAR、7Z、TAR.GZ,最大 35MB),别人在详情页一键下载;只放链接不带附件也可以。
工具按大家的收藏热度排序,好用的自然会被顶上来。发布后可在详情页或卡片菜单里编辑、下架。
写笔记时勾上“隐藏”,这篇就只存在于你自己的账号里:不进列表、不进搜索、不上首页精选,也不会出现在任何公开的页面,链接发给别人同样打不开。
适合放密码、草稿、日记这类只给自己看的内容;想公开,去“发布”打开它,把“隐藏”的勾去掉再保存,之后编辑会默认保持原状态,不会悄悄变回公开。
你的内容会同时保存在多个副本上,系统定期做备份与完整性校验,再配合异地容灾机制:就算某台机器出问题,数据也不会丢,可以长期放心存放;特别重要的资料,仍建议你另外再留一份备份。
全站跑在容器化、模块化的现代架构上,更新、部署、回滚都很快,扩展性和稳定性都按长期运营的标准来设计(Built for reliability, designed to scale)。
这个网站最早只是一个人的笔记仓库,后来慢慢长成现在的知识中枢。设计上很克制——没有广告、没有追踪、没有推荐算法,只是干干净净地存放一些东西;既然做好了,就公开出来,万一有人用得上呢。
不做大而全,不做平台梦,保持简单、保持克制、保持好奇。所有内容都由用户贡献、由用户维护:不会突然冒出付费墙,不会在角落塞广告位,也不会把你的数据卖给第三方。
产品会持续迭代,站内日志页记录着每一次改动,改了什么都有迹可循;想了解这个站是怎么一步步走到今天的,翻翻日志就能看到来龙去脉。
如果在这里看到涉嫌违规的内容,点对应卡片右侧的“举报”按钮就能提交,我们会尽快核实处理;也谢谢你花一点时间,一起把这里维护干净。
如何用纯 HTML 和 CSS 实现深色模式切换(无需 JavaScript)
为什么我们要让网站不依赖 JavaScript?
先说一个可能有点反直觉的观点:你的网站应该在没有 JavaScript 的情况下也能正常工作。我不是说让你完全不用 JS,而是说它应该是一个渐进增强(progressive enhancement)的选项,而不是根基。
这些年我做了不少静态网站生成器(SSG)的项目,比如 Hugo、Eleventy 这些。它们一个共同点就是:生成出来的页面本身就是完整的 HTML,不需要 JS 才能看到内容。我自己的博客、WikiZEIT 项目,还有我那个叫“Complite”的 Eleventy 起始模板,都用了我自己折腾出来的这个深色模式切换方案——纯 HTML + CSS,零 JavaScript。
你可能要问:现在谁还不用 JS 啊?有这个必要吗?
有。而且原因比你想象的更实际。
1. 无障碍(Accessibility)
虽然现代屏幕阅读器已经能处理一些 JS 渲染的页面了,但这不是唯一的考量。有些人还在用老电脑、老手机,浏览器可能不支持最新的 JS 特性。还有些人网络很差,直接关掉了 JS 来省流量。你希望这些用户也能正常访问你的内容吧?
2. SEO
Google 是少数几个能比较好地渲染 JS 页面的爬虫,但它依然需要额外的时间和资源去执行 JS。相比之下,直接返回的服务器端 HTML 几乎是瞬间就能被索引。如果你的页面是纯客户端渲染的 React 应用,爬虫可能只看到 <div id="root"></div> 这一行——直到 JS 下载并执行完。这对 SEO 来说是个隐患。
3. AI 爬虫和答案引擎
现在越来越多的 AI 爬虫(比如 OpenAI、Anthropic 的抓取工具)并不像浏览器那样执行 JS。它们直接读原始 HTML 响应。如果你的内容要靠 JS 才能渲染出来,AI 可能根本看不到。
所以结论很明确:让网站在没有 JS 的情况下也能展示内容,是对人和机器都更友好的做法。
当然,这不意味着你非得写纯 HTML + CSS。你可以用 React,但最好搭配 Next.js 的 SSR 或 SSG,或者直接用 Hugo、Eleventy 这样的静态站点生成器。我本人是 Eleventy 的忠实用户,也写过相关教程。
HTML 结构:就两个 radio 按钮
好,道理讲完了,咱们直接上手。这个深色模式切换的 HTML 核心就是两个 radio 按钮:
<div class="theme-toggle">
<input type="radio" id="mode_dark" name="mode" value="dark">
<label for="mode_dark" aria-label="切换到深色模式"> 🌙 </label>
<input type="radio" id="mode_light" name="mode" value="light">
<label for="mode_light" aria-label="切换到浅色模式"> ☀️ </label>
</div>
注意几点:
- 两个 radio 按钮的
name相同,所以是互斥的——你只能选一个。 - 每个 input 都有一个对应的
label,并且我们用了aria-label来提升无障碍体验。 - 图标用的是月亮和太阳 emoji,简单直观。
这个结构本身没有任何 JS,就是纯 HTML。
CSS 核心::has() 选择器才是真正的魔法
现在到了最精彩的部分。我们要用 CSS 的 :has() 伪类来判断当前选中了哪个 radio 按钮。
:has() 有点像“父选择器”——CSS 社区盼了好多年终于盼到了。比如 p:has(img) 会匹配所有包含图片的 <p> 标签。而在我们的场景里,我们可以这样写:
html:has(#mode_dark:checked) p {
color: white;
background: black;
}
意思就是:如果页面上有一个 id 为 mode_dark 的 radio 按钮被选中了,那么所有 <p> 标签都变成白字黑底。
反过来,html:has(#mode_light:checked) 就可以定义浅色模式。
就是这么简单。不需要任何 JS 监听事件,不需要 class 切换,纯 CSS 就完成了状态管理。
美化切换按钮:让太阳和月亮只显示一个
光有功能还不够,我们得让这个切换按钮看起来像那么回事。核心思路是:任何时候只显示一个图标,而且默认显示的是系统偏好对应的那个。
/* 容器布局 */
.theme-toggle {
display: flex;
align-items: center;
}
/* 彻底隐藏 radio 按钮本身 */
.theme-toggle input[type="radio"] {
appearance: none;
-webkit-appearance: none;
margin: 0;
position: absolute;
opacity: 0;
pointer-events: none;
}
/* 让 label 变成一个可点击的 40x40 区域 */
.theme-toggle label {
width: 40px;
height: 40px;
display: grid;
place-items: center;
cursor: pointer;
}
接下来是关键:默认情况下,显示月亮(深色模式图标),隐藏太阳。但如果用户系统偏好是深色模式,则反过来。
/* 默认(浅色系统偏好):显示月亮,隐藏太阳 */
label[for="mode_light"] {
display: none;
}
label[for="mode_dark"] {
display: grid;
}
/* 如果用户系统偏好是深色模式:显示太阳,隐藏月亮 */
@media (prefers-color-scheme: dark) {
label[for="mode_light"] {
display: grid;
}
label[for="mode_dark"] {
display: none;
}
}
然后,当用户手动切换后,我们要用 :has() 覆盖掉默认状态:
/* 用户手动选了深色模式:显示太阳(表示可以切回浅色) */
:root:has(#mode_dark:checked) label[for="mode_light"] {
display: grid;
}
:root:has(#mode_dark:checked) label[for="mode_dark"] {
display: none;
}
/* 用户手动选了浅色模式:显示月亮(表示可以切回深色) */
:root:has(#mode_light:checked) label[for="mode_light"] {
display: none;
}
:root:has(#mode_light:checked) label[for="mode_dark"] {
display: grid;
}
这里有个小细节值得注意:切换按钮上显示的是你将要切换到的模式图标。比如当前是深色模式,按钮上就显示太阳,点击后变成浅色模式。这符合直觉——用户看到太阳就知道点一下会变亮。
CSS 变量:让主题切换覆盖整个页面
最后一步,也是让整个方案真正可用的关键:用 CSS 变量来控制页面的所有颜色。
我们可以在 :root 上定义变量,然后用 :has() 和 @media 来给变量赋值:
/* 系统偏好:深色模式 */
@media (prefers-color-scheme: dark) {
:root {
--bg: #252525; /* 深灰 */
--fg: #fff; /* 白色 */
}
}
/* 用户手动选了深色模式 */
:root:has(#mode_dark:checked) {
--bg: #252525;
--fg: #fff;
}
/* 用户手动选了浅色模式 */
:root:has(#mode_light:checked) {
--bg: #fff; /* 白色 */
--fg: #252525; /* 深灰 */
}
然后在整个页面的 CSS 里,你只需要引用这些变量:
body {
background: var(--bg);
color: var(--fg);
}
这样一来,你就不需要到处写 html:has(#mode_dark:checked) p { color: white; } 这种重复代码了。所有颜色定义集中管理,清晰又干净。
当然,实际项目中你可能不止两个变量。你可能会有 --link-color、--border-color、--shadow 等等。但原理完全一样。
总结一下
这个方案的核心思路其实很简单:
- 用 radio 按钮存储用户选择(不需要 JS 变量或 localStorage)。
- 用 CSS 的
:has()伪类检测选中状态,并据此改变样式。 - 用
@media (prefers-color-scheme: dark)尊重系统偏好,作为默认值。 - 用 CSS 变量集中管理所有颜色,让代码更干净。
最终效果是:一个完全不需要 JavaScript 的深色模式切换按钮,而且它尊重用户系统偏好,用户可以手动覆盖。
如果你对这个方案感兴趣,可以看看我做的 CodePen 演示,或者直接去我的博客和 WikiZEIT 项目里看实际效果。
最后再说一句:渐进增强是个好习惯。先让 HTML + CSS 把事情做好,再考虑用 JS 锦上添花。这样你的网站对所有人、所有爬虫都更友好。
有任何问题可以 Twitter/X 上找我,我开着 DM。也可以看看我的个人博客。