CSS - Bullet threading
Source
I found this on Reddit, posted by user seashoreandhorizon.
Setup
Go to Settings
, Appearance
, and scroll all the way down to the CSS snippets
section. You might already have some there, or not. It does not matter for us.
Click on the folder icon. This should open the local folder containing the snippets. Create a new file and give it a name that makes sense to you. For example, bullet threading.css
. Make sure that the file extension is css
. If you don't see your file extensions, click on View
, Show
, and File name extensions
(in Windows Explorer).
Now open the file and copy the CSS code below into it. Save the file, go back to Obsidian and refresh the list of snippets. Enable the bullet threading
one, and that should do it. If it does not, you may have to restart Obsidian.
Result
This snippet will automatically add a "guiding line" from the top level entry in a list to the entry over which you are hovering your mouse:
Code
//comment
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3, .HyperMD-list-line-2):hover)::after,
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-2:hover, ~ .HyperMD-list-line-2 ~ :is(.HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6):hover)::before,
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6):hover))::before {
--list-threading-color: hsl(23, 100%, 45%, 1);
--list-threading-offset: calc(4px + 0.15em);
}
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3):hover)::after,
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-3:hover, ~ .HyperMD-list-line-3 ~ :is(.HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6):hover)::before,
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6):hover))::before {
--list-threading-color: hsl(46, 100%, 45%, 1);
--list-threading-offset: calc(4px + 0.15em + 2em);
}
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4):hover)::after,
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-4:hover, ~ .HyperMD-list-line-4 ~ :is(.HyperMD-list-line-5, .HyperMD-list-line-6):hover)::before,
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-5, .HyperMD-list-line-6):hover))::before {
--list-threading-color: hsl(70, 100%, 45%, 1);
--list-threading-offset: calc(4px + 0.15em + 2 * 2em);
}
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5):hover)::after,
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-5:hover, ~ .HyperMD-list-line-5 ~ :is(.HyperMD-list-line-6):hover)::before,
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-6):hover))::before {
--list-threading-color: hsl(105, 100%, 45%, 1);
--list-threading-offset: calc(4px + 0.15em + 3 * 2em);
}
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6):hover)::after,
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-6:hover)::before,
.HyperMD-list-line-6:not(:has(~ .HyperMD-list-line-6 ~ .HyperMD-list-line:hover)):is(:hover)::before {
--list-threading-color: hsl(187, 100%, 45%, 1);
--list-threading-offset: calc(4px + 0.15em + 4 * 2em);
}
/* tails */
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3, .HyperMD-list-line-2):hover)::after,
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3):hover)::after,
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4):hover)::after,
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5):hover)::after,
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6):hover)::after {
content: "";
position: absolute;
left: var(--list-threading-offset);
bottom: 0;
height: 0.8em;
width: 2px;
background-color: var(--list-threading-color);
}
.HyperMD-list-line.HyperMD-task-line::after {
max-height: 0.275em;
}
/* in-between lines */
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-2:hover, ~ .HyperMD-list-line-2 ~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3):hover)::before,
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-3:hover, ~ .HyperMD-list-line-3 ~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4):hover)::before,
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-4:hover, ~ .HyperMD-list-line-4 ~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5):hover)::before,
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-5:hover, ~ .HyperMD-list-line-5 ~ :is(.HyperMD-list-line-6):hover)::before,
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-6:hover)::before {
content: "";
position: absolute;
left: var(--list-threading-offset);
top: 0;
height: 100%;
width: 2px;
background-color: var(--list-threading-color);
}
/* elbows */
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3):hover))::before,
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4):hover))::before,
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5):hover))::before,
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-6):hover))::before,
.HyperMD-list-line-6:not(:has(~ .HyperMD-list-line-6 ~ .HyperMD-list-line:hover)):is(:hover)::before {
content: "";
position: absolute;
left: var(--list-threading-offset);
width: 2em;
top: 0;
height: calc(100% - 0.825em - var(--outline-guideline-width) / 2);
border-bottom-left-radius: var(--radius-m);
border-bottom: 3px solid var(--list-threading-color);
border-left: 3px solid var(--list-threading-color);
}
.HyperMD-list-line.HyperMD-task-line::before {
max-width: calc(2em - 0.35em);
}
body {
--outline-guideline-width: var(--size-2-1);
--outline-guideline-color: var(--color-accent);
--outline-item-height: calc(var(--nav-item-size) * 1.8);
}
li {
position: relative;
}
/* In-between items */
li:hover > ul > li:has(~li:hover)::before {
content: "";
width: 3px;
position: absolute;
background-color: var(--outline-guideline-color);
top: calc(var(--outline-item-height) / 2 * -1);
left: calc(-2px - 2em - var(--size-4-4));
height: calc(100% - var(--outline-item-height) + var(--size-4-8) + 2px);
}
/* Elbows items */
li:hover > ul > li:hover::before {
content: "";
position: absolute;
top: calc(var(--outline-item-height) / 2 * -1);
left: calc(-2px - 2em - var(--size-4-4));
bottom: calc(100% - (var(--outline-item-height) + var(--size-4-2)) / 2 + 1px);
width: calc(1em + var(--size-4-4) - 2px);
border-bottom-left-radius: var(--radius-m);
border-bottom: 3px solid var(--outline-guideline-color);
border-left: 3px solid var(--outline-guideline-color);
}
/* Outline Bullet Threading*/
body {
--accent-active: var(--color-accent);
/* 引导线粗细 */
--outline-guideline-width: 3px;
/* 引导线颜色 */
--outline-guideline-color: var(--accent-active);
/* 一行高度 */
--outline-item-height: calc(var(--nav-item-size) * 1.8);
}
.workspace-leaf-content[data-type=outline] .view-content .outline {
--line-height-tight: var(--outline-item-height);
}
.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: -1px;
/* fix item gap */
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self::before {
content: "";
width: var(--size-4-5);
height: calc(var(--outline-item-height) + var(--size-4-2));
position: absolute;
left: calc(var(--size-4-4) * -1);
top: 0;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self .tree-item-inner {
padding-left: var(--size-4-1);
}
.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;
top: 50%;
transform: translate(calc(-1 * var(--size-4-5)), -50%);
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-self .tree-item-icon ~ .tree-item-inner {
padding-left: var(--size-4-1);
}
.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: -14px;
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;
transform: translateY(var(--size-2-3));
}
.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: 3px;
top: 50%;
transform: translateY(-50%);
z-index: 10;
}
.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: -14px;
bottom: calc(100% - (var(--outline-item-height) + var(--size-4-2)) / 2 - 1px);
width: var(--size-4-6);
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);
z-index: 9;
}
.workspace-leaf-content[data-type=outline] .view-content .outline :is(.tree-item-children, .tree-item-self) {
padding-left: 28px !important;
margin-left: 0 !important;
border-left: none;
}
.workspace-leaf-content[data-type=outline] .view-content .outline .tree-item-inner:empty {
height: var(--outline-item-height);
}
Bullet Threading.css
Displaying Bullet Threading.css.