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

When you paste the code into the file outline.css use ctrl+shift+v rather than ctrl+v.
Try that and see if it works.

Unfortunately still no effect is shown. Do you have another idea? Thanks!

I am using Obsidian 1.0.3 on Windows btw.

I’m on windows 10 and it works ok for me. Only thing I can think of is your theme might be overriding it? If you can, post a screenshot of your outline panel so we can see what is showing.

My outline looks like this:
grafik
I am with my cursor on test1, in dark mode and in live mode. I tried reading mode as well.

I am on the default theme and have the snippet enabled:

The contents of outline.css is the code copied from @subframe7536. Do you need anything else?

Thank you!

1 Like

Yeah that does not look right. The only thing I changed was the line I posted above as the lines were not lining up for me, so you can try that. Also restart Obsidian if you have not already. Otherwise delete the file and recreate it making sure to use ctrl+shift+v to paste it in (code copied from the forum will not format properly with normal ctrl+v pasting).

Here is my snippet with the one change, try this one.

/* 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 {
  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: 7px;
  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: -10px;
  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: 50%;
  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: -10px;
  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

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