Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Float Tables

demo

飞书文档风格的 Obsidian 宽表格:初始态与正文栏对齐,宽表向右浮出正文栏;横向滚动时列滑进两侧出血区,滚到底两侧收齐;边缘用柔和阴影提示「这边还有内容」。窄表完全不受影响。

Feishu/Lark-style wide tables for Obsidian: tables start aligned with the text column, float out into the pane's margins as you scroll, and show soft edge shadows as scroll hints. Narrow tables are untouched. The README below explains the full mechanism — feel free to feed it to your agent and reimplement it your way.

为什么

Obsidian 默认把表格硬塞进正文可读行宽:列被挤压、inline code 被拦腰折行、日期折成三行。飞书文档的答案是让表格「浮」在正文之上——先尽量展示内容,实在放不下才滚动。这个插件把那套行为搬进 Obsidian,纯 CSS 实现,不改 DOM、不监听事件、零性能开销,reading view 和 live preview 行为一致。

安装(BRAT)

  1. 安装 BRAT 插件
  2. BRAT 设置 → Add beta plugin → 填本仓库地址
  3. 在设置里启用 Float Tables

设置项四个:总开关、边缘留白(默认 2em)、长文案列封顶宽(默认 34em,超过则换行)、滚动阴影浓度(0 关闭)。

实现原理(欢迎拿去自己实现)

核心是三个 CSS 机制的叠加,没有一行 JS 参与布局(main.js 只做设置面板和写 CSS 变量)。完整样式见 styles.css,可以直接抄成 snippet 用,不装插件也行。

1. 让「面板」而不是「正文栏」成为宽度基准

表格的包装元素(reading view 的 .el-table、live preview 的 .cm-table-widget)的包含块是正文栏(受 readable line width 约束,100% ≈ 700px),但我们要浮出到整个编辑面板。Container query 解决取宽问题:

.markdown-preview-view,
.markdown-source-view.mod-cm6 {
  container-type: inline-size;
}

之后后代样式里的 100cqw 就是面板宽度,100% 是正文栏宽度——两个基准同时可用。

2. 负 margin 扩宽 + 等量 padding 回缩 = 「初始对齐、滚动浮出、末端收齐」

.el-table, .cm-table-widget {
  --ft-bleed: max(0px, calc((100cqw - 100%) / 2 - 2em));
  margin-inline: calc(0px - var(--ft-bleed)) !important;
  padding-inline: var(--ft-bleed);
  overflow-x: auto;
}
  • margin-inline滚动视口扩到面板出血区(两侧各留 2em)
  • 等量正 padding-inline内容起点拉回正文栏左缘——所以初始态首列精确对齐正文;滚动时列滑进左侧出血区;由于尾部 padding 参与滚动溢出,滚到底时尾列同样收在对齐位
  • 窄表:内容不溢出 → 不滚动 → padding 让它呆在原地,视觉零变化。不需要 JS 测量「表格是否溢出」,几何本身就是自适应的
  • !important 是必要的:Obsidian 自带 .cm-embed-block { margin-inline: -16px },优先级压过普通选择器(这是踩坑实测,别删)

3. 滚动提示阴影:background-attachment: local 经典技巧

background:
  linear-gradient(90deg, var(--background-primary) 30%, transparent) left/32px 100%,
  linear-gradient(270deg, var(--background-primary) 30%, transparent) right/32px 100%,
  radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.08), transparent) left/10px 100%,
  radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.08), transparent) right/10px 100%;
background-repeat: no-repeat;
background-attachment: local, local, scroll, scroll;

两层「遮罩」渐变(用页面背景色)attach 为 local,跟内容一起滚;两层阴影 attach 为 scroll,钉在视口边缘。哪一侧滚到头,遮罩就盖住那一侧的阴影——阴影只在「这边还有隐藏内容」时出现。这是 Lea Verou 的经典技巧,表格单元格背景透明所以直接可用。

4. 配套宽度模型(让浮出有意义)

table { width: max-content; max-width: none; }  /* 列取自然宽度,不被挤压 */
td { max-width: 34em; }                          /* 长文案列封顶换行 */
td code { white-space: nowrap; }                 /* code token 永不拦腰折断 */

没有这一段,表格永远不会比正文栏宽,前面的一切都不会触发。

踩坑备忘(双视图一致性)

  • Obsidian reading view 和 live preview 是两套完全不同的 DOM。选择器必须成对写:.markdown-rendered .el-table.markdown-source-view.mod-cm6 .cm-table-widget
  • Live preview 的表格 widget 同时带有 .markdown-rendered class,所以 td / code 级规则写 .markdown-rendered 一份即可覆盖两侧,但 wrapper 级(margin/padding)必须分开写
  • 验证对齐别靠肉眼:DevTools 里量 table.getBoundingClientRect().left - content.getBoundingClientRect().left,等于 0 才算对齐

边界与已知限制

  • 需要 Obsidian ≥ 1.6(container queries + .el-table DOM)
  • 「Readable line length」关闭时正文栏 ≈ 面板宽,浮出量自然趋近于 0,行为退化为普通横滚,符合直觉
  • 只处理表格。代码块 / Mermaid / 图片的浮出是同一套几何,抄 styles.css 换选择器即可——这正是把原理写清楚的意义

License

MIT。随便用,随便改,不用告诉我。

About

Float tables like in Feishu/Lark docs for Obsidian — wide tables break out of the text column and scroll in place

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages