样式修改、主题制作 深入教程/经验分享

大前提:有一定的 css 基础

  1. 大部分常用的样式改动可以通过内置的变量解决

    1. --h1-color 指等级为 1 的标题颜色

    2. --line-height-normal 指编辑器内的文字行高

    3. 属性值可以通过 --h1-color: red; 的方式修改,所有的变量在 devtools 中 source 面板的 app.css,也可以看这里

    4. 为了更好的显示效果,宽度推荐使用 var(--size-x-x)

  2. 慎用 !important,它会提高你的维护成本。如果遇到第一点的样式修改不生效的问题,推荐使用在具体的元素上修改,而不是在 body 上修改

    1. 其实更推荐使用最新的 @layer 修改 (不过我没去看过 2333

    2. 如果需要修改的样式原本直接写在元素上,大胆使用 !important

  3. 合理利用 :is() 或者 :not() 减少代码,安装版本为最新版的 obsidian ,可以使用 @container:has()

    1. :is() :not() 内不能是 ::before 或者 ::after 等伪元素

    2. @container 可以让容器内元素根据容器宽度进行媒体响应,具体应用可以参考我的主题中文本内搜索框部分
      container-query

    3. :has() 通过判断是否包含某个元素实现了该功能,包括选择当前元素的父元素和前一个兄弟元素,具体应用可以参考我的主题中预览模式代码美化部分

  4. clamp() 函数很有用

  5. 引用 quote 的缩进不要更改,OB 是通过 js 实时计算的,自己修改会很麻烦

  6. 使用好 chrome devtools、Theme Design Utilities 插件

    1. devtools

      1. 获取元素选择器路径:选中元素 → 右键 → copy → copy selector

      2. 模拟 hover、active 等状态:Styles 面板,右上角: hov,点击选中

      3. 查看元素最终显示的属性:Computed 面板,点击可以跳转到对应的样式

      4. 查看当前元素的父元素(查找绝对定位元素的父元素很有用):点击箭头,选择 Properties,查找 parentElement

    2. Theme Design Utilities

      1. 社区插件可以直接搜素

      2. Freeze Obsidian:在修改一些失去焦点就会消失的元素很有用,使用须打开 devtools

      3. Mobile Emulation:修改移动端样式时使用

      4. 其他功能也挺不错的

  7. 这个 是 pdf 的 dom 节点,一些修改的样式不生效是因为 .print 上的 css 变量和 body 上自带的 css 变量一致,所以如果需要修改 pdf 的样式,最好在 css 变量的选择器上加 .print

  8. 字体的使用可以通过 @font-face 进行简化,转换为 base64 目前使用的是 ctool,也有 utools 版,使用更加方便。字体特性可以通过 font-feature-settings 属性开启

  9. 自定义图标

    1. 使用 unocss 的思路,将原本的图标通过 -webkit-mask-image 进行替换,内容使用svg

    2. 找图标: Icônes

    3. 压缩和转义 svg: https://www.zhangxinxu.com/sp/svgo/

    4. 找到要替换的元素,设置 background-color: currentColor;-webkit-mask-size: 100% 100%;,如果本身是 svg,需要再对子元素 path 加上 display:none;

    5. 对替换的元素添加 -webkit-mask-image: url('data:image/svg+xml;utf8,压缩后的svg');

    6. 如果未生效,在 <svg ...>...</svg> 中添加作用域,变成 <svg xmlns="http://www.w3.org/2000/svg" ...>...</svg>

    7. 可以参考我的代码(使用 sass,但是原理类似)

10 个赞

弱弱的问下,现在能用css实现标题自动编号吗?据说以前的版本不行,不知道最近的版本可不可以

无解,ob的节点还是动态更新的,文章一长,编号会乱

修复:PDF的DOM节点

1 个赞

分享的非常棒!咋没人顶?

在修改一些失去焦点就会消失的元素很有用

失去焦点消失这个原理是setTimeout(()=>{debugger}, 5000) 这个非常棒!在浏览器环境也可以这样模拟,非常有用!

引用 quote 的缩进不要更改,OB 是通过 js 实时计算的

编辑器里的元素,比如样式啥的,都不能通过js动态修改,只要改了,瞬间就复原,需要通过上层元素来配合修改才行。

不止如此,现在树结构(比如文件管理器)的缩进也不能动,最近修复的时候恶心坏了

哦哦,文件列表树结构我倒是没改过

请教下大佬,怎样才能做到 左边栏的节点为目录时,如果为空,调整条目的字体透明度或者其他样式?

.nav-folder:not(:has(.nav-folder-children)) {
  opacity: 0.5;
}

编辑:上面的不太对,文件夹没有打开的时候也会变灰,下面这个是正确的逻辑

.nav-folder:not(:has(>.nav-folder-children), .is-collapsed) {
  opacity: 0.5;
}

好像不生效
image

分享一个可以在打印后查看当前页面 PDF DOM 节点的插件 obsidian-print-preview,具体使用请查看插件说明。

一般样式修改关注顶层 DOM 差异即可,也就是加 .print 之类的。但部分中层元素依然存在一些棘手的差异,比如嵌入标题和嵌入块在 PDF 中没有文档中的多层结构,只在父元素下以兄弟元素排成一列最终渲染结果(测试版本 1.8.7),所以可能会出现在编辑和阅读模式下均成功应用 CSS 隐藏的元素,打印时却仍显示,因为 PDF 中无对应选择器。为了快速找出此类问题根源,就适合使用该插件。

大佬,请教!!!

想要实现的是:隐藏被引用的笔记的最高一级的标题
比如我引用了一篇笔记,这篇笔记的最高标题是 一级标题,那就隐藏这个一级标题,但显示一级标题下一行开始的所有内容
如果我引用了一篇笔记其中的某一个二级标题及其以下的所有内容,那就仅隐藏这个二级标题,但显示这个二级标题下一行开始的所有内容
如果我引用了一篇笔记其中的某一个三级标题及其以下的所有内容,那就仅隐藏这个三级标题,但显示这个三级标题下一行开始的所有内容
以此类推

试过了各种隐藏title的css,要么都没用,要么就是隐藏了所有的标题。。。

我的主题里面就有这个功能

Maple Editor > 内嵌块 > 内嵌文件标题移至右上角

源码在 src/editor/embed.scss

感谢大佬指路。
我一般不用社区主题,就是直接用的css

经过大佬指路,结合你的主题功能(完全就是我想要的功能)
努力与AI进行了无数轮对话,调试,终于形成了仅css实现这个功能

隐藏被引用的笔记的最高一级的标题
比如我引用了一篇笔记,这篇笔记的最高标题是 一级标题,那就隐藏这个一级标题,但显示一级标题下一行开始的所有内容
如果我引用了一篇笔记其中的某一个二级标题及其以下的所有内容,那就仅隐藏这个二级标题,但显示这个二级标题下一行开始的所有内容
如果我引用了一篇笔记其中的某一个三级标题及其以下的所有内容,那就仅隐藏这个三级标题,但显示这个三级标题下一行开始的所有内容
以此类推

留个代码,可能有其他人会需要:

.internal-embed.is-loaded:not([alt="#"]) .markdown-embed-heading .markdown-preview-section > div:nth-child(2) {
  right: 12px;
}

.internal-embed.is-loaded:not([alt="#"]) .obsidian-metatable {
  display: none;
}

.internal-embed.is-loaded:not([alt="#"]):not([src*="#^"]) .embed-title:empty + .markdown-embed-content .markdown-preview-section > div:nth-child(3) {
  position: absolute;
  right: 24px;
  top: 8px;
  z-index: 99;
  opacity: 0;
  transition: opacity 0.15s ease-in-out;
}

.internal-embed.is-loaded:not([alt="#"]):not([src*="#^"]) .embed-title:empty + .markdown-embed-content .markdown-preview-section > div:nth-child(3) * {
  font-size: 1rem;
  cursor: pointer;
  line-height: 1rem;
}

.internal-embed.is-loaded:not([alt="#"]) .markdown-embed-title {
  opacity: 0;
  position: absolute;
  z-index: 99;
  width: fit-content;
  right: 28px;
  left: unset;
  font-size: 1rem;
  top: 4px;
  line-height: 28px;
  height: 28px;
  padding: 0 8px;
  transition: opacity 0.15s ease-in-out;
  cursor: pointer;
}

.internal-embed.is-loaded:not([alt="#"]):hover .embed-title:empty + .markdown-embed-content .markdown-preview-section > div:nth-child(3) {
  opacity: 1;
}

.internal-embed.is-loaded:not([alt="#"]):hover :is(.markdown-embed-title, .markdown-embed-link, .file-embed-link:hover svg) {
  opacity: 1;
  color: var(--text-normal);
}

.internal-embed.is-loaded:not([alt="#"]) :is(.markdown-embed, .file-embed) .markdown-preview-view {
  padding: calc(var(--font-text-size, 16px) * 1.5);
  padding-bottom: calc(var(--font-text-size, 16px) * 1.2);
}

/* 兼容性调整,确保在不同主题下都能正常显示 */
.markdown-preview-view .internal-embed {
  position: relative;
}

.markdown-embed-title {
  background: var(--background-primary, #ffffff);
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* 暗色模式适配 */
.theme-dark .markdown-embed-title {
  background: var(--background-primary, #1e1e1e);
}