My css snippets for outline, inspired by logseq bullet threading plugin

Been playing around with this some more and I just noticed that in my theme Blue Topaz it still shows a bit of the drop down arrow? Tried this in 10 different themes as well as the default theme and it works great in all of them except for ITS Theme which is completely messed up and, like I said Blue Topaz which looks good other than a bit of the drop down arrow is still showing (Have not been able to get rid of that).

Thank you for the advice. Unfortunately, still no bullet threading is shown for me.

I took the following steps:

  1. Open Obsidian Sandbox vault (Help → Sandbox vault)
  2. Go to Settings → Appearance → CSS snippets and open the folder
  3. Create a new file called outline.css
  4. Open the file with VS Code
  5. Copy the snippet from your post, paste it with Ctrl+Shift+V and save the file
  6. Go back to Obsidian → Appearance and enable the snippet outline

This did not change anything for me. I tried both light and dark theme as well as live mode and read mode.
I then installed Blue Topaz and tried it again with light and dark theme as well as live mode and read mode without success:

I don’t even see anything messed up, as if the snippet is not enabled.
Did you enable anything else is the settings? Maybe you could try the steps above as well to see if it still works for you in a new/different vault.

@willasm I figured it out!

Apparently I misunderstood what this snippet was for. I was under the impression that bullet threading would work for any list whereas this snippet is for the outline view (on the left panel) only.

In the outline view it works great! Thank you for your help.

Do you know if something similar is possible for a list within a note?

2 Likes

Sorry, not that I’m aware of. I have several themes installed and none of them do anything to lists.

I see, thank you for your support @willasm!

sorry, but it can’t until the version of electron update to 21+ officially :smiling_face_with_tear:.there is no hierarchy in the dom tree of editor area, so i can’t get the preceding node without :has selector. this selector is only supported in electron 21+. so currently it only effect in outline panel

Pretty sure obsidian is now officially updated to electron 21? At least, I’ve been using the has: selector in snippets for the last month or so, and it’s been working perfectly. (And I would love to have bullet threading in obsidian as demo’d, it’s something I really miss from logseq. But the CSS magic is a bit beyond my basic capabilities…)

hello!
everyday i check if there is already a bullet threading plugin lol
the only reason I haven’t moved entirely from logseq to obsidian is bullet threading
I use manymany bullets and get lost without it
does that snippet works? I

Although I have made several attempts, I have come to realize that the task is more challenging than anticipated and currently beyond my capabilities.:smiling_face_with_tear:Using :has() selector will cause serious performance issue

Currently, the method to achieve the effect in the editor using pure CSS is

  1. to give all the list elements and outline elements in the editor a hierarchical structure (which conflicts with the element design philosophy for the live preview mode);
  2. to add a class name at the beginning of each list to identify it (which obviously will not be considered based on the design philosophy like quotes and code blocks or the limitations of CodeMirror itself).

Hi @subframe7536, the outline core plugin of Obsidian was updated and and using your css snippet, the outline is not aligned anymore.

Do you have an updated version of the snippet?

I checked your obsidian-theme-maple theme and found outline.css and theme.css but I am not sure what the relevant parts are that are needed for this snippet.

Thanks for your help!

I’ve modify it to adapt to the new Obsidian version, here is it:

/* Outline CSS Snippet
https://forum.obsidian.md/t/my-css-snippets-for-outline-inspired-by-logseq-bullet-threading-plugin/48558
*/
body {
  --outline-guideline-width: var(--size-2-1);
  --outline-guideline-color: var(--accent-active);
  --outline-item-height: calc(var(--nav-item-size) * 1.8);
  /*active color*/
  --accent-active: hsl(var(--accent-h),
      var(--accent-s),
      calc(var(--accent-l) + 4%));
}

.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item {
  position: relative;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self {
  position: relative;
  margin-bottom: 0;
  white-space: nowrap;
  margin-top: -5px !important;
  /* fix item gap */
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self .tree-item-inner {
  position: relative;
  padding-left: var(--size-4-4);
  overflow: hidden;
  text-overflow: ellipsis;
  height: var(--outline-item-height);
  line-height: var(--outline-item-height);
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self .tree-item-inner::before {
  content: "";
  width: var(--size-4-1);
  height: var(--size-4-1);
  border: var(--size-2-1) solid var(--outline-guideline-color);
  border-radius: 50%;
  position: absolute;
  left: 0px;
  top: 50%;
  transform: translateY(-50%);
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self .tree-item-icon ~ .tree-item-inner {
  padding-left: var(--size-4-4); /* Changed from 'var(--size-4-1);' now looks right */
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self .tree-item-icon ~ .tree-item-inner::before {
  content: none;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item.is-collapsed .tree-item-icon::before {
  box-shadow: 0 0 0 var(--size-4-1) var(--background-modifier-hover);
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item::after {
  content: "";
  width: var(--outline-guideline-width);
  position: absolute;
  background-color: transparent;
  top: calc(var(--outline-item-height) / 2 * -1);
  left: -6px;
  height: calc(100% - var(--outline-item-height) + var(--size-4-8));
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-icon {
  cursor: pointer;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-icon::before {
  width: var(--size-4-2);
  height: var(--size-4-2);
  background-color: var(--outline-guideline-color);
  border-radius: 50%;
  position: absolute;
  left: 7px;
  top: 120%;
  transform: translateY(-50%);
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-icon svg path {
  display: none;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item:hover > .tree-item-children > .tree-item::after {
  background-color: var(--outline-guideline-color);
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item:hover > .tree-item-self:hover + .tree-item-children .tree-item::after {
  background-color: transparent;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item:hover > .tree-item-children > .tree-item:hover::after, .workspace-leaf-content[data-type=outline] .view-content .outline .tree-item:hover > .tree-item-children > .tree-item:hover ~ .tree-item::after {
  background-color: transparent;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item:hover > .tree-item-children > .tree-item:hover::before {
  content: "";
  position: absolute;
  top: calc(var(--outline-item-height) / 2 * -1);
  left: -6px;
  bottom: calc(100% - (var(--outline-item-height) + var(--size-4-2)) / 2 - 1px);
  width: var(--size-4-4);
  border-bottom-left-radius: var(--radius-m);
  border-bottom: var(--outline-guideline-width) solid var(--outline-guideline-color);
  border-left: var(--outline-guideline-width) solid var(--outline-guideline-color);
}
.workspace-leaf-content[data-type=outline] .view-content .outline :is(.tree-item-children, .tree-item-self .tree-item-self) {
  padding-left: 0;
  margin-left: var(--size-4-5);
  border-left: none;
}

1 Like

Thank you @SharpZhou.

However, the alignment and the bullets are displayed incorrectly for me. See here:

It appear to be related whether a heading has a subheading itself. When adding a subheading below # 1.2 or # 2 the indentation and bullet is correct:

update version in Chinese Forum: 大纲美化V3修复版 - 经验分享 - Obsidian 中文论坛

1 Like

Hi! I don’t know why, but the snippet stopped working. It could be due to:

  • updated Obsidian from 1.4.13 to 1.4.14;
  • updated my Macbook to MacOS 14.0 Sonoma.

I don’t know why these updates should impact only this snippet and not all the others, but it’s the only thing I could think about.

To prevent possible questions:

  • I have not changed themes, I’m currently using Minimal theme btw.
  • I have not installed, enabled, disabled or altered in any way any community plugin.
  • Yesterday I enabled the core plugin workspaces, but I don’t think there’s any correlation, and disabling it doesn’t produce any effect.

Any idea how to fix or at least what’s the reason for this?

Experiencing the same issue since I updated to 1.4.14 as well, the snippet just does not work anymore. Any way to rectify the same? Cheers.

1 Like

@LSKY @NK8 updated in Chinese Forum: 大纲美化片段 v1.4.14 修复 - 经验分享 - Obsidian 中文论坛

4 Likes

Hi, thanks for clearing that up. Works perfectly well now, just encountering an issue where if the heading is a little too long - it tends to get cut off. Unlike in the core outline plugin where it jumps to the next line. Have attached a picture showcasing the issue. Could you let me know if there is any potential workaround? Thanks a ton.

1 Like

Currently the bullet height is determined by line height. If the item have multi lines, the bullet will render in wrong place that break the thread. That need some work to fix that.

I plan to add support for outline in editor ( reference ), and this might be fixed at that time

1 Like

As the author of the referenced style for the editor, I’m also not aware of a way to know for sure where the bullet point is drawn. That is unless you have an idea how to alter the thread design, so it doesn’t interfere with the bullet point position.
Multiline items and inline images affect the bullet point position differently -it can potentially be anywhere along the height of the item if the item is higher than trivial one-line text.

(side note: there are some feature requests under my gist, I plan to update it at some point, hopefully soon, although I might be busy for a couple weeks)

2 Likes