Freeze first row and column in tables

Use case or problem

It’s not easy to read and to complete large tables because the header and first column disappear on scrolling.

Proposed solution

Adding the ability to freeze the first row and column (EDIT: or maybe set it by default for all tables).

(For the columns, there is a css property sticky but can’t manage to make it work with a snippet).

Thank you for taking the time to read me and thank you to make Obsidian so convenient to use !

8 Likes

This may be hard to implement since you don’t want to freeze the first row by default. And what should happen after you revisit the note later, should you see the fixed row or not? In what cases the fixed row state is preserved and where that information should be stored. What happens if there are multiple tables in one note?

Thank you for your message and your thoughts about it. You’re right, if this make it easier, the header could be fixed by default.

About the possiblity for a page to contain several tables, there are a lot of tutos with live demos on sticky property showing it can be possible with just few lines of css with or without javascript.

Like this one : https://codepen.io/jonaspas/pen/QamXaM

I am not enough skilled to implement it, but bases on these examples, it seems apparently not very hard to add this feature.

And it could be I think a very appreciated because currently, I do not see a lot of people using Obsidian for large table except through special plugins.

1 Like

I have the same request, it would make browsing large tables much easier.

1 Like

With the current implementation of Obsidian only parts of larger documents are loaded into memory, which means that the top of a table could very well be unloaded when scrolling in a longer table.

This in turn means, it’s not just as easy as many tutorials say to just add a little CSS to make this happen. Obsidian would either need to counter what one (or both) of the markdown engines currently do, or get the markdown engines to keep entire documents loaded at all times.

I’m not sure if neither feasible, or wanted on a general level. Although, I’ve looked into doing related stuff myself, so I would’ve like the opportunity to do this at some level.

1 Like

I would hope the unloading is based on the size of the actual document – since it’s markdown, all my files, even the largest ones, are in the double-digit kb-range. That’s so tiny, it’s unheard of and almost negligible in today’s computing world. (I do still remember 1.44MB floppy drives.)

I also support adding a frozen first-row option. Otherwise, larger tables are unusable in Obsidian.

/* ====== 阅读视图容器处理 ====== /
.markdown-reading-view .markdown-preview-sizer {
/
Obsidian阅读视图特有的包装元素 /
transform: none !important;
/
清除Obsidian默认应用的变换属性,防止干扰粘性定位 */
}

/* ====== 强制创建新层叠上下文 ====== /
.markdown-preview-view table, /
实时预览模式下的表格元素 /
.markdown-source-view.mod-cm6 .cm-table-widget, /
源码模式下的表格容器组件 /
.markdown-reading-view table { /
阅读视图下的表格元素 /
transform: translateZ(0);
/
通过3D变换触发GPU加速,创建独立渲染层 /
isolation: isolate;
/
隔离元素的层叠上下文,防止z-index冲突 /
contain: style layout paint;
/
现代CSS优化属性:限制浏览器重绘范围,提升滚动性能 */
}

/* ====== 表头行基础样式 ====== /
.markdown-preview-view thead tr, /
实时预览表头行 /
.markdown-source-view.mod-cm6 thead tr, /
源码模式表头行 /
.markdown-reading-view thead tr { /
阅读视图表头行 /
background-color: rgba(52, 152, 219, 0.05) !important;
/
设置基础半透明蓝色背景(RGBA透明度5%) */
}

/* ====== 蓝色毛玻璃表头核心样式 ====== /
.markdown-preview-view thead tr th, /
实时预览表头单元格 /
.markdown-source-view.mod-cm6 .cm-table-widget thead tr th, /
源码模式表头单元格 /
.markdown-reading-view thead tr th { /
阅读视图表头单元格 /
position: sticky !important;
/
使用粘性定位实现冻结效果 /
top: 0 !important;
/
固定到容器顶部 /
z-index: 500 !important;
/
设置足够高的层级,确保覆盖下方内容 */

background: rgba(33, 150, 243, 0.15) !important;
/* 叠加更高浓度的蓝色层(透明度15%)*/

box-shadow: 0 1px 3px rgba(3, 102, 214, 0.09) !important;
/* 添加浅蓝色投影增加层次感 */

backdrop-filter: /* 现代CSS滤镜组合 /
blur(8px) /
高斯模糊创造毛玻璃效果 /
brightness(1.18) /
亮度补偿(避免模糊导致变暗) /
hue-rotate(195deg); /
色相旋转增强蓝色调 */
}

/* ====== 阅读视图滚动容器修复 ====== /
.markdown-reading-view .markdown-preview-section {
overflow: visible !important;
/
解除外层容器的滚动限制(Obsidian默认设置为auto) */
}

.markdown-reading-view .markdown-preview-section > div {
overflow: visible !important;
/* 解除内层div的滚动限制,确保表格能正常溢出 */
}

/* ====== 源码模式容器修复 ====== /
.markdown-source-view.mod-cm6 .cm-table-widget {
overflow: visible !important;
/
允许源码模式下的表格溢出容器 */
}

/* =============== 当前单元格高亮 =============== /
.markdown-preview-view td:hover, /
实时预览单元格悬停 /
.markdown-source-view.mod-cm6 td:hover, /
源码模式单元格悬停 /
.markdown-reading-view td:hover { /
阅读视图单元格悬停 /
outline: 2px solid rgba(255, 165, 0, 0.7) !important;
/
使用outline替代border(不影响布局) /
position: relative;
/
创建新的定位上下文 /
z-index: 501;
/
设置高于表头的层级(500+1) */
}

/* ===== 表格十字定位 ===== /
/
=============== 表格容器基础设置 =============== /
.markdown-preview-view table,
.markdown-source-view.mod-cm6 table {
overflow: visible !important; /
允许内容溢出,确保列高亮效果可见 /
position: relative; /
为子元素的绝对定位创建参照基准 */
}

/* =============== 单元格基础样式 =============== /
.markdown-preview-view td,
.markdown-source-view.mod-cm6 td {
position: relative; /
为伪元素定位建立坐标系 /
overflow: visible !important;/
允许伪元素溢出单元格 /
transition: background-color 0.2s; /
背景色过渡动画 */
}

/* =============== 行高亮效果 =============== /
.markdown-preview-view tr:hover td,
.markdown-source-view.mod-cm6 tr:hover td {
background: rgba(52, 152, 219,0.08) !important;
/
使用!important覆盖斑马纹优先级,透明度8%的蓝色背景 /
border-top: 2px solid rgba(52, 152, 219, 0.8); /
上部淡色边框 /
border-bottom: 2px solid rgba(52, 152, 219, 0.8); /
底部淡色边框 */

}

/* =============== 列高亮效果 =============== /
.markdown-preview-view td:hover::after,
.markdown-source-view.mod-cm6 td:hover::after {
content: ‘’; /
必须属性,创建伪元素 /
position: absolute; /
绝对定位脱离文档流 /
top: -9999px; /
向上延伸至无限远 /
bottom: -9999px; /
向下延伸至无限远 /
left: 0; /
从单元格左侧开始 /
right: 0; /
覆盖整个单元格宽度 /
background: rgba(52, 152, 219, 0); /
列背景色 /
z-index: -1; /
置于单元格内容下方 /
pointer-events: none; /
防止伪元素阻挡鼠标事件 /
border-left: 2px solid rgba(191, 97, 106, 0.8); /
左侧淡色边框 /
border-right: 2px solid rgba(191, 97, 106, 0.8); /
右侧淡色边框 */
}

Related