不能直接修改jupyter notebook内置markdown渲染器默认样式,但可通过custom.css(最稳妥,需重启服务)或ipython.display.html动态注入(仅当前notebook生效)实现;须使用.text_cell_render等精确选择器,避免被覆盖。

不能直接改 Jupyter Notebook 内置 Markdown 渲染器的默认样式——它用的是前端静态渲染,没有全局 CSS 注入入口;但可以通过自定义 custom.css 或运行时注入 style 标签绕过限制,效果稳定且无需重启内核。
修改 custom.css 是最稳妥的方式
这个文件由 Jupyter 在启动时自动加载,影响所有 Notebook 的 Markdown 单元格(包括导出 HTML),适合长期统一风格。
- 找到或创建用户级 custom 目录:
~/.jupyter/custom/(Linux/macOS)或%USERPROFILE%\.jupyter\custom\(Windows) - 在该目录下新建
custom.css,写入 CSS 规则,例如:
/* 修改所有 Markdown 段落的行高和字体大小 */
.text_cell_render p {
line-height: 1.6;
font-size: 15px;
}
/* 调整 h2 标题颜色和间距 */
.text_cell_render h2 {
color: #2c3e50;
margin-top: 24px;
margin-bottom: 12px;
}
保存后重启 Jupyter Notebook 服务(不是刷新页面),新样式才会生效。
用 IPython.display.HTML 动态注入样式
适合单个 Notebook 临时调试,或需要按需切换主题的场景。它只作用于当前 Notebook,不污染全局。
- 在任意代码单元格中运行:
from IPython.display import HTML, display
display(HTML("""
<style>
.text_cell_render h3 { color: #e74c3c; }
.text_cell_render ul { padding-left: 24px; }
</style>
"""))
注意:<style></style> 必须写在 display(HTML(...)) 中,不能直接写 HTML 标签;且该样式仅对后续执行的 Markdown 单元格生效,已渲染的需手动重新运行。
为什么改 .text_cell_render 而不是 body?
Jupyter 把每个 Markdown 单元格包裹在独立的 <div class="text_cell_render"> 里,全局 CSS(如 <code>body p)会被内联样式或更具体的规则覆盖,导致失效。
- 直接写
p { ... }基本无效,因为优先级太低 -
.text_cell_render p或.jp-RenderedHTMLCommon p(JupyterLab 用)才匹配实际 DOM 结构 - JupyterLab 和 Classic Notebook 的类名不同,
custom.css不通用,别混用
常见失败原因:路径、缓存、选择器错位
改完没反应?大概率卡在这三处。
-
custom.css文件名必须全小写、无空格、无扩展名错误(比如写成custom.CSS或custom.css.txt) - 浏览器缓存了旧 CSS,强制刷新(
Ctrl+Shift+R或Cmd+Shift+R) - 用浏览器开发者工具检查元素,确认目标标签是否真有
.text_cell_render类——某些插件(如 jupyter-themes)会覆盖结构,导致选择器失效
真正起效的样式一定得贴着 Jupyter 的实际 DOM 路径写,而不是照搬普通网页经验。











