Skip to content

Instantly share code, notes, and snippets.

@KillyMXI
Last active August 28, 2024 14:41
Show Gist options
  • Save KillyMXI/cbef8edff6dd55d9e6ea4df66567e9b1 to your computer and use it in GitHub Desktop.
Save KillyMXI/cbef8edff6dd55d9e6ea4df66567e9b1 to your computer and use it in GitHub Desktop.
Obsidian list threading and highlight in live preview and source view

Obsidian live-preview list threading and highlight

Obsidian forum thread: https://forum.obsidian.md/t/plugin-for-bullet-threading/37317/22

Add these CSS files in Appearance settings.

Changelog:

  • 2024-08-15

    • separate versions for mouse hover and active line (keyboard focus)
      • can be enabled simultaneously without conflicts
    • works in live preview and source view
    • configurable with Style Settings plugin
    • threading snippets now have priority for wrapped text by default, can be toggled to priority for images
    • default styles adjusted to keep hover and active line threading distinguishable while using same color palette
    • threading line offsets are fixed to match latest Obsidian styles
  • 2023-10-02

    • highlight snippet
      • halved the alpha, making highlight more subtle
      • made 6th color a bit more distinct from 5th
    • threading snippet
      • removed accidental dependency on another CSS snippet
      • adjusted offsets to better match indentation lines with the default font size
      • using --list-indent variable to hopefully make the snippet more compatible with styles that alter it
      • providing height calculations that prioritize wrapped text over images (or any other oversized inline content with default vertical alignment) - requires manual edits in 3 places to switch

Support me if you'd like me to publish Obsidian things more often:

https://github.com/sponsors/KillyMXI

/* @settings
name: Live preview list highlight - active line
id: live-preview-list-highlight-active
settings:
-
id: colors-section
title: Colors
type: heading
level: 2
collapsed: false
-
id: list-highlight-active-alpha
title: Alpha
description: The alpha (transparency) of all highlights
type: variable-number-slider
default: 0.05
min: 0.0
max: 1.0
step: 0.05
-
id: style-settings-bug-note
title: Note
description: "Style Settings seems to be [bugged](https://github.com/mgmeyers/obsidian-style-settings/issues/168). You may not see the actual colors here before interacting with each color picker."
type: info-text
markdown: true
-
id: list-highlight-active-color-1
title: Color 1
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(23, 100%, 45%)'
-
id: list-highlight-active-color-2
title: Color 2
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(46, 100%, 45%)'
-
id: list-highlight-active-color-3
title: Color 3
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(70, 100%, 45%)'
-
id: list-highlight-active-color-4
title: Color 4
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(105, 100%, 45%)'
-
id: list-highlight-active-color-5
title: Color 5
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(187, 100%, 45%)'
-
id: list-highlight-active-color-6
title: Color 6
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(223, 100%, 45%)'
*/
.HyperMD-list-line-1.cm-active,
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-2, .HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6).cm-active) {
background-color: hsl(var(--list-highlight-active-color-1, 23, 100%, 45%), var(--list-highlight-active-alpha, 0.05));
}
.HyperMD-list-line-2.cm-active,
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6).cm-active) {
background-color: hsl(var(--list-highlight-active-color-2, 46, 100%, 45%), var(--list-highlight-active-alpha, 0.05));
}
.HyperMD-list-line-3.cm-active,
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6).cm-active) {
background-color: hsl(var(--list-highlight-active-color-3, 70, 100%, 45%), var(--list-highlight-active-alpha, 0.05));
}
.HyperMD-list-line-4.cm-active,
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-5, .HyperMD-list-line-6).cm-active) {
background-color: hsl(var(--list-highlight-active-color-4, 105, 100%, 45%), var(--list-highlight-active-alpha, 0.05));
}
.HyperMD-list-line-5.cm-active,
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6).cm-active) {
background-color: hsl(var(--list-highlight-active-color-5, 187, 100%, 45%), var(--list-highlight-active-alpha, 0.05));
}
.HyperMD-list-line-6.cm-active {
background-color: hsl(var(--list-highlight-active-color-6, 223, 100%, 45%), var(--list-highlight-active-alpha, 0.05));
}
/* @settings
name: Live preview list highlight - on hover
id: live-preview-list-highlight-hover
settings:
-
id: colors-section
title: Colors
type: heading
level: 2
collapsed: false
-
id: list-highlight-hover-alpha
title: Alpha
description: The alpha (transparency) of all highlights
type: variable-number-slider
default: 0.05
min: 0.0
max: 1.0
step: 0.05
-
id: style-settings-bug-note
title: Note
description: "Style Settings seems to be [bugged](https://github.com/mgmeyers/obsidian-style-settings/issues/168). You may not see the actual colors here before interacting with each color picker."
type: info-text
markdown: true
-
id: list-highlight-hover-color-1
title: Color 1
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(23, 100%, 45%)'
-
id: list-highlight-hover-color-2
title: Color 2
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(46, 100%, 45%)'
-
id: list-highlight-hover-color-3
title: Color 3
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(70, 100%, 45%)'
-
id: list-highlight-hover-color-4
title: Color 4
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(105, 100%, 45%)'
-
id: list-highlight-hover-color-5
title: Color 5
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(187, 100%, 45%)'
-
id: list-highlight-hover-color-6
title: Color 6
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(223, 100%, 45%)'
*/
.HyperMD-list-line-1:hover,
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-2, .HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6):hover) {
background-color: hsl(var(--list-highlight-hover-color-1, 23, 100%, 45%), var(--list-highlight-hover-alpha, 0.05));
}
.HyperMD-list-line-2:hover,
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6):hover) {
background-color: hsl(var(--list-highlight-hover-color-2, 46, 100%, 45%), var(--list-highlight-hover-alpha, 0.05));
}
.HyperMD-list-line-3:hover,
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6):hover) {
background-color: hsl(var(--list-highlight-hover-color-3, 70, 100%, 45%), var(--list-highlight-hover-alpha, 0.05));
}
.HyperMD-list-line-4:hover,
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-5, .HyperMD-list-line-6):hover) {
background-color: hsl(var(--list-highlight-hover-color-4, 105, 100%, 45%), var(--list-highlight-hover-alpha, 0.05));
}
.HyperMD-list-line-5:hover,
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6):hover) {
background-color: hsl(var(--list-highlight-hover-color-5, 187, 100%, 45%), var(--list-highlight-hover-alpha, 0.05));
}
.HyperMD-list-line-6:hover {
background-color: hsl(var(--list-highlight-hover-color-6, 223, 100%, 45%), var(--list-highlight-hover-alpha, 0.05));
}
/* @settings
name: Live preview list threading - active line
id: live-preview-list-threading-active
settings:
-
id: list-threading-active-elbow-location
title: Threading line elbow location
description: Where the threading line elbow is located
type: class-select
allowEmpty: false
default: list-threading-active-elbow-top
options:
-
label: "Top (priority for wrapped text)"
value: list-threading-active-elbow-top
-
label: "Bottom (priority for images)"
value: list-threading-active-elbow-bottom
-
id: list-threading-active-width
title: Threading line width
description: The width of the threading line
type: variable-number
default: 3
format: px
-
id: list-threading-active-offset-extra
title: Thread line extra offset
description: Extra offset for threading line
type: variable-number
default: 2
format: px
-
id: colors-section
title: Colors
type: heading
level: 2
collapsed: false
-
id: list-threading-active-alpha
title: Alpha
description: The alpha (transparency) of all threading lines
type: variable-number-slider
default: 0.2
min: 0.0
max: 1.0
step: 0.05
-
id: style-settings-bug-note
title: Note
description: "Style Settings seems to be [bugged](https://github.com/mgmeyers/obsidian-style-settings/issues/168). You may not see the actual colors here before interacting with each color picker."
type: info-text
markdown: true
-
id: list-threading-active-color-1
title: Color 1
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(23, 100%, 45%)'
-
id: list-threading-active-color-2
title: Color 2
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(46, 100%, 45%)'
-
id: list-threading-active-color-3
title: Color 3
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(70, 100%, 45%)'
-
id: list-threading-active-color-4
title: Color 4
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(105, 100%, 45%)'
-
id: list-threading-active-color-5
title: Color 5
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(187, 100%, 45%)'
*/
.markdown-source-view .HyperMD-list-line {
/* Unitless zero in variables is evil */
--list-padding-inline-start-fix: 0px; /*calc(1px * var(--list-indent-source));*/
}
.markdown-source-view.is-live-preview .HyperMD-list-line {
--list-padding-inline-start-fix: var(--list-indent-editing);
}
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3, .HyperMD-list-line-2).cm-active),
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-2.cm-active, ~ .HyperMD-list-line-2 ~ :is(.HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6).cm-active),
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-3, .HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6).cm-active)) > .cm-hmd-list-indent {
&::before {
--list-threading-active-color: hsl(var(--list-threading-active-color-1, 23, 100%, 45%), var(--list-threading-active-alpha, 0.2));
--list-threading-active-offset: calc(var(--list-threading-active-offset-extra, 2px) + var(--list-padding-inline-start-fix));
}
}
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3).cm-active),
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-3.cm-active, ~ .HyperMD-list-line-3 ~ :is(.HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6).cm-active),
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-4, .HyperMD-list-line-5, .HyperMD-list-line-6).cm-active)) > .cm-hmd-list-indent {
&::before {
--list-threading-active-color: hsl(var(--list-threading-active-color-2, 46, 100%, 45%), var(--list-threading-active-alpha, 0.2));
--list-threading-active-offset: calc(var(--list-threading-active-offset-extra, 2px) + var(--list-padding-inline-start-fix) + var(--list-indent));
}
}
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4).cm-active),
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-4.cm-active, ~ .HyperMD-list-line-4 ~ :is(.HyperMD-list-line-5, .HyperMD-list-line-6).cm-active),
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-5, .HyperMD-list-line-6).cm-active)) > .cm-hmd-list-indent {
&::before {
--list-threading-active-color: hsl(var(--list-threading-active-color-3, 70, 100%, 45%), var(--list-threading-active-alpha, 0.2));
--list-threading-active-offset: calc(var(--list-threading-active-offset-extra, 2px) + var(--list-padding-inline-start-fix) + 2 * var(--list-indent));
}
}
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5).cm-active),
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-5.cm-active, ~ .HyperMD-list-line-5 ~ :is(.HyperMD-list-line-6).cm-active),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-6).cm-active)) > .cm-hmd-list-indent {
&::before {
--list-threading-active-color: hsl(var(--list-threading-active-color-4, 105, 100%, 45%), var(--list-threading-active-alpha, 0.2));
--list-threading-active-offset: calc(var(--list-threading-active-offset-extra, 2px) + var(--list-padding-inline-start-fix) + 3 * var(--list-indent));
}
}
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6).cm-active),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-6.cm-active),
.HyperMD-list-line-6:not(:has(~ .HyperMD-list-line-6 ~ .HyperMD-list-line.cm-active)):is(.cm-active) > .cm-hmd-list-indent {
&::before {
--list-threading-active-color: hsl(var(--list-threading-active-color-5, 187, 100%, 45%), var(--list-threading-active-alpha, 0.2));
--list-threading-active-offset: calc(var(--list-threading-active-offset-extra, 2px) + var(--list-padding-inline-start-fix) + 4 * var(--list-indent));
}
}
/* tails */
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3, .HyperMD-list-line-2).cm-active),
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3).cm-active),
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4).cm-active),
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5).cm-active),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line.cm-active)):has(~ :is(.HyperMD-list-line-6).cm-active) {
&::before {
content: "";
position: absolute;
left: var(--list-threading-active-offset);
bottom: 0;
width: var(--list-threading-active-width, 3px);
background-color: var(--list-threading-active-color);
height: calc(100% - 0.75em);
}
.is-live-preview &:is(.HyperMD-task-line)::before {
max-height: calc(100% - 1.3em);
}
body.list-threading-active-elbow-bottom &::before {
height: 0.8em;
}
body.list-threading-active-elbow-bottom .is-live-preview &:is(.HyperMD-task-line)::before {
max-height: 0.275em;
}
}
/* in-between lines */
.HyperMD-list-line-1:not(:has(~ .HyperMD-list-line-1 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-2.cm-active, ~ .HyperMD-list-line-2 ~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3).cm-active),
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-3.cm-active, ~ .HyperMD-list-line-3 ~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4).cm-active),
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-4.cm-active, ~ .HyperMD-list-line-4 ~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5).cm-active),
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-5.cm-active, ~ .HyperMD-list-line-5 ~ :is(.HyperMD-list-line-6).cm-active),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line.cm-active)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-6.cm-active) {
&::before {
content: "";
position: absolute;
left: var(--list-threading-active-offset);
top: 0;
height: 100%;
width: var(--list-threading-active-width, 3px);
background-color: var(--list-threading-active-color);
}
}
/* elbows */
.HyperMD-list-line-2:not(:has(~ .HyperMD-list-line-2 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4, .HyperMD-list-line-3).cm-active)),
.HyperMD-list-line-3:not(:has(~ .HyperMD-list-line-3 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5, .HyperMD-list-line-4).cm-active)),
.HyperMD-list-line-4:not(:has(~ .HyperMD-list-line-4 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-6, .HyperMD-list-line-5).cm-active)),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line.cm-active)):is(.cm-active, :has(~ :is(.HyperMD-list-line-6).cm-active)),
.HyperMD-list-line-6:not(:has(~ .HyperMD-list-line-6 ~ .HyperMD-list-line.cm-active)):is(.cm-active) {
& > .cm-hmd-list-indent::before {
content: "";
position: absolute;
left: var(--list-threading-active-offset);
width: calc(var(--list-indent) - var(--list-threading-active-width, 3px));
top: 0;
border-bottom-left-radius: var(--radius-m);
border-bottom: var(--list-threading-active-width, 3px) solid var(--list-threading-active-color);
border-left: var(--list-threading-active-width, 3px) solid var(--list-threading-active-color);
height: calc(0.775em);
}
body.list-threading-active-elbow-bottom & > .cm-hmd-list-indent::before {
height: calc(100% - 0.825em - var(--list-threading-active-width, 3px) / 2);
}
.is-live-preview &:is(.HyperMD-task-line) > .cm-hmd-list-indent::before {
max-width: calc(var(--list-indent) - 0.35em - var(--list-threading-active-offset-extra, 2px));
}
}
/* @settings
name: Live preview list threading - on hover
id: live-preview-list-threading-hover
settings:
-
id: list-threading-hover-elbow-location
title: Threading line elbow location
description: Where the threading line elbow is located
type: class-select
allowEmpty: false
default: list-threading-hover-elbow-top
options:
-
label: "Top (priority for wrapped text)"
value: list-threading-hover-elbow-top
-
label: "Bottom (priority for images)"
value: list-threading-hover-elbow-bottom
-
id: list-threading-hover-width
title: Threading line width
description: The width of the threading line
type: variable-number
default: 1
format: px
-
id: list-threading-hover-offset-extra
title: Thread line extra offset
description: Extra offset for threading line
type: variable-number
default: 4
format: px
-
id: colors-section
title: Colors
type: heading
level: 2
collapsed: false
-
id: list-threading-hover-alpha
title: Alpha
description: The alpha (transparency) of all threading lines
type: variable-number-slider
default: 0.4
min: 0.0
max: 1.0
step: 0.05
-
id: style-settings-bug-note
title: Note
description: "Style Settings seems to be [bugged](https://github.com/mgmeyers/obsidian-style-settings/issues/168). You may not see the actual colors here before interacting with each color picker."
type: info-text
markdown: true
-
id: list-threading-hover-color-1
title: Color 1
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(23, 100%, 45%)'
-
id: list-threading-hover-color-2
title: Color 2
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(46, 100%, 45%)'
-
id: list-threading-hover-color-3
title: Color 3
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(70, 100%, 45%)'
-
id: list-threading-hover-color-4
title: Color 4
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(105, 100%, 45%)'
-
id: list-threading-hover-color-5
title: Color 5
type: variable-color
opacity: false
format: hsl-values
default: 'hsl(187, 100%, 45%)'
*/
.markdown-source-view .HyperMD-list-line {
/* Unitless zero in variables is evil */
--list-padding-inline-start-fix: 0px; /*calc(1px * var(--list-indent-source));*/
}
.markdown-source-view.is-live-preview .HyperMD-list-line {
--list-padding-inline-start-fix: var(--list-indent-editing);
}
.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),
.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),
.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)) > .cm-hmd-list-indent {
&::after {
--list-threading-hover-color: hsl(var(--list-threading-hover-color-1, 23, 100%, 45%), var(--list-threading-hover-alpha, 0.4));
--list-threading-hover-offset: calc(var(--list-threading-hover-offset-extra, 4px) + var(--list-padding-inline-start-fix));
}
}
.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),
.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),
.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)) > .cm-hmd-list-indent {
&::after {
--list-threading-hover-color: hsl(var(--list-threading-hover-color-2, 46, 100%, 45%), var(--list-threading-hover-alpha, 0.4));
--list-threading-hover-offset: calc(var(--list-threading-hover-offset-extra, 4px) + var(--list-padding-inline-start-fix) + var(--list-indent));
}
}
.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),
.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),
.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)) > .cm-hmd-list-indent {
&::after {
--list-threading-hover-color: hsl(var(--list-threading-hover-color-3, 70, 100%, 45%), var(--list-threading-hover-alpha, 0.4));
--list-threading-hover-offset: calc(var(--list-threading-hover-offset-extra, 4px) + var(--list-padding-inline-start-fix) + 2 * var(--list-indent));
}
}
.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),
.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),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-6):hover)) > .cm-hmd-list-indent {
&::after {
--list-threading-hover-color: hsl(var(--list-threading-hover-color-4, 105, 100%, 45%), var(--list-threading-hover-alpha, 0.4));
--list-threading-hover-offset: calc(var(--list-threading-hover-offset-extra, 4px) + var(--list-padding-inline-start-fix) + 3 * var(--list-indent));
}
}
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):has(~ :is(.HyperMD-list-line-6):hover),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-6:hover),
.HyperMD-list-line-6:not(:has(~ .HyperMD-list-line-6 ~ .HyperMD-list-line:hover)):is(:hover) > .cm-hmd-list-indent {
&::after {
--list-threading-hover-color: hsl(var(--list-threading-hover-color-5, 187, 100%, 45%), var(--list-threading-hover-alpha, 0.4));
--list-threading-hover-offset: calc(var(--list-threading-hover-offset-extra, 4px) + var(--list-padding-inline-start-fix) + 4 * var(--list-indent));
}
}
/* 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),
.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),
.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),
.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),
.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-hover-offset);
bottom: 0;
width: var(--list-threading-hover-width, 1px);
background-color: var(--list-threading-hover-color);
height: calc(100% - 0.75em);
}
.is-live-preview &:is(.HyperMD-task-line)::after {
max-height: calc(100% - 1.3em);
}
body.list-threading-hover-elbow-bottom &::after {
height: 0.8em;
}
body.list-threading-hover-elbow-bottom .is-live-preview &:is(.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),
.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),
.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),
.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),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)) ~ .HyperMD-list-line:has(~ .HyperMD-list-line-6:hover) {
&::after {
content: "";
position: absolute;
left: var(--list-threading-hover-offset);
top: 0;
height: 100%;
width: var(--list-threading-hover-width, 1px);
background-color: var(--list-threading-hover-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)),
.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)),
.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)),
.HyperMD-list-line-5:not(:has(~ .HyperMD-list-line-5 ~ .HyperMD-list-line:hover)):is(:hover, :has(~ :is(.HyperMD-list-line-6):hover)),
.HyperMD-list-line-6:not(:has(~ .HyperMD-list-line-6 ~ .HyperMD-list-line:hover)):is(:hover) {
& > .cm-hmd-list-indent::after {
content: "";
position: absolute;
left: var(--list-threading-hover-offset);
width: calc(var(--list-indent) - var(--list-threading-hover-width, 1px));
top: 0;
border-bottom-left-radius: var(--radius-m);
border-bottom: var(--list-threading-hover-width, 1px) solid var(--list-threading-hover-color);
border-left: var(--list-threading-hover-width, 1px) solid var(--list-threading-hover-color);
height: calc(0.775em);
}
body.list-threading-hover-elbow-bottom & > .cm-hmd-list-indent::after {
height: calc(100% - 0.825em - var(--list-threading-hover-width, 1px) / 2);
}
.is-live-preview &:is(.HyperMD-task-line) > .cm-hmd-list-indent::after {
max-width: calc(var(--list-indent) - 0.35em - var(--list-threading-hover-offset-extra, 4px));
}
}
@pulkitgoyal56
Copy link

Hey, this looks awesome! Thanks! :)

But it doesn't seem to work like it does in your screenshots.

image

I switched off all the other CSS snippets in my vault and the issue persists.

Do you think there's some problem with my setup?
Perhaps some compatibility issues with another plugin?

@KillyMXI
Copy link
Author

KillyMXI commented Oct 1, 2023

@pulkitgoyal56

I found the reason why you don't see elbows. I used the variable --outline-guideline-width from the CSS snippet for threading in the read mode. It went unnoticed because, apparently, everyone including me uses that snippet along with mine. I will do additional checks and change the gist tomorrow, in order to remove the dependency. Following part from that snippet makes this work, so you can fix it now:

body {
  --outline-guideline-width: var(--size-2-1);
}

Something else affects list indentation for you. I don't know what standard settings can cause this. Tab indent size or Readable line length in the Editor settings doesn't do this for me.

You may try Restricted mode in Community plugins settings to quickly check it without plugins.

Themes - I use Standard, and also tried Minimal - it seems not affecting indentation sizes.

If you know how to use DevTools (Ctrl+Shift+I) - you might be able to find which styles affect the indentation, albeit that might be nontrivial.

@KillyMXI
Copy link
Author

KillyMXI commented Oct 2, 2023

@pulkitgoyal56

I updated the gist.
In case something in your vault changes the --list-indent variable - threading should work fine for you now.

@pulkitgoyal56
Copy link

pulkitgoyal56 commented Oct 2, 2023

@KillyMXI

Yeah, that fixed the elbows. Thanks!

Also for pointing out the indentation issue. It turns out, it's because I am using spaces for indentation (I have the settings Editor > Indent using tabs turned off), and the snippet doesn't seem to work with spaces.

For 3 spaces, it overshoots (see below), and for 4, it undershoots like above.

Is it possible to update the snippet so that it works with spaces as well?


I digress, but on that note, I also investigated this further and found that Tab indent size setting in Obsidian doesn't affect lists, which seem to have a fixed tab size, and their indentation is also unfased by the text font.

If I use the default font, Inter, it looks like this,
image

And if I use any other monospace font, in this case Fira Code (same results with Consolas), it looks like this,
image

Notice (for the second, monospace font case) how the tab size is not an integer number of spaces; it's somewhere between 3 and 4!


The compromise I guess is to just use tabs for indentation, but as a Python programmer it feels violating.

FYI, I am using the default theme. I am new to Obsidian, and have no experience with CSS.

@KillyMXI
Copy link
Author

KillyMXI commented Oct 2, 2023

@pulkitgoyal56

Thanks for investigating and finding the cause.
Yeah, initially I thought to use spaces as well, but somehow realized I'll be fighting windmills sooner or later. This is a case where tabs are more reliable, because the editor is inherently non-monospace, and various live-preview components use it in whatever way they like.
And on top of that, the editor component itself - the one behind live-preview and source mode - produces garbage HTML.
Indentation guide lines are not even shown correctly when you use spaces for indentation.

I'm afraid I can't make this work universally.

  • if you can stick with the same number of spaces - you should be able to edit --list-threading-offset values for all 5 offsets to the indentation values you get on screen;
  • otherwise, accept the tabs.

@pulkitgoyal56
Copy link

pulkitgoyal56 commented Oct 2, 2023

Thanks for the directions; I was able to modify it to get the following with 4 spaces.

image

I changed the following,

  • --list-threading-offset -> calc(7px + <n> * 39.5px)
  • --list-indent -> 39.5px

Looks great! :)

@lasseeboe
Copy link

Very nice! Is it possible to make the threading stick on cursor position instead of mouse position?

@KillyMXI
Copy link
Author

KillyMXI commented Oct 12, 2023

@lasseeboe good question.
And the answer is Yes!

Find and replace with your code editor of choice all :hover with .cm-active, and it seems to work nicely!

( Ctrl+H hotkey is typically used for the replace operation in many editors, please don't try to replace them one by one manually. I hope this is trivial enough, so I don't have to make a separate copy. )

@neuromaancer
Copy link

neuromaancer commented Oct 21, 2023

Hi This is excellent! Thank you very much! However, I have an issue, it works fine if I use the mouse, but I am a Vim user, so I actually use vim motion with vim obsidian plugin. I think this snippet won't allow me to do the same thing with vim cursor. Especially in Vim normal mode.

@pulkitgoyal56
Copy link

pulkitgoyal56 commented Oct 21, 2023

@lasseeboe good question. And the answer is Yes!

Find and replace with your code editor of choice all :hover with .cm-active, and it seems to work nicely!

( Ctrl+H hotkey is typically used for the replace operation in many editors, please don't try to replace them one by one manually. I hope this is trivial enough, so I don't have to make a separate copy. )

I use the Vim plugin as well and it works perfectly with this change.

I actually use both the mouse hover version and the cursor version together.

That setup also mostly works. Although there are cases where it doesn't work perfectly. Like having the cursor and mouse on different items at the same sublist level, the vertical line is not proper. Maybe @KillyMXI, would you suggest any modifications to make it work better in that setup? (It'd also be very nice if these two could be made visually more different, like maybe dotted lines for one and solid lines for the other, but I suppose that requires more changes. Any comments there?)

@KillyMXI
Copy link
Author

Oh gosh.
I was thinking how to make a combined version that would follow either the keyboard cursor or mouse, giving priority to mouse.
Making separate threading for keyboard and mouse might be possible, will try to pull it off without compromises.
Quick answer: With a compromise of losing tails, it is certainly possible - one copy will use ::before, the other copy will use ::after pseudo-element.

Dotted lines may not work very well - each thread is composed of small fragments - there are going to be a lot of visual artifacts.
When there are two threads, I would rather assign each one a constant color regardless of depth. Assuming low alpha, two distinct enough hues may blend well enough to see how they overlap.
Other tools to distinguish them are line offset and thickness.

@justanotherjurastudent
Copy link

Hi,
It bothered me a bit that the elbow doesn't stay linked to the beginning of the bullet point if the list has more than one line. So I adjusted the css a little so that the elbow always remains linked to the start of the list. Here's the code:

.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%, 0.3);
  --list-threading-offset: calc(5px + 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%, 0.3);
  --list-threading-offset: calc(5px + 0.15em + var(--list-indent));
}

.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%, 0.3);
  --list-threading-offset: calc(5px + 0.15em + 2 * var(--list-indent));
}

.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%, 0.3);
  --list-threading-offset: calc(5px + 0.15em + 3 * var(--list-indent));
}

.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%, 0.3);
  --list-threading-offset: calc(4px + 0.15em + 4 * var(--list-indent));
}

/* 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: calc(var(--list-threading-offset) + 6px);
  top: 1.2em;
  bottom: 0;
  /* priority to wrapped text */
  
  width: var(--size-2-1);
  background-color: var(--list-threading-color);
}
.HyperMD-list-line.HyperMD-task-line::after {
  /* priority to wrapped text */
  max-height: calc(100% - 1.3em);
  /* priority to images */
  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: calc(var(--list-threading-offset) + 6px);
  top: 0;
  height: 100%;
  width: var(--size-2-1);
  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: calc(var(--list-threading-offset) + 6px);
  width: calc(var(--list-indent) - 6px);
  top: 0;
  /* priority to wrapped text */
  height: 0.75em;
  border-bottom-left-radius: var(--radius-m);
  border-bottom: var(--size-2-1) solid var(--list-threading-color);
  border-left: var(--size-2-1) solid var(--list-threading-color);
}
.HyperMD-list-line.HyperMD-task-line::before {
  max-width: calc(var(--list-indent) - 0.35em);
}

@KillyMXI
Copy link
Author

KillyMXI commented Aug 15, 2024

Timely nudge...
I was able to focus on the improved version, long overdue.

@pulkitgoyal56 I was able to keep two full versions of threading completely apart from each other, so it is now possible to enjoy it both for active line (kb cursor) and mouse hover.
By default, they are distinguished by width and opacity. But colors are also adjustable.

two-threading-lines

@X012C
Copy link

X012C commented Aug 19, 2024

image
I am new to obsidian. I loaded the CSS in the default theme but it didn't take effect. I don't know which step I missed. I hope to get help.

@justanotherjurastudent
Copy link

justanotherjurastudent commented Aug 19, 2024

image I am new to obsidian. I loaded the CSS in the default theme but it didn't take effect. I don't know which step I missed. I hope to get help.

@X012C You have to save the CSS code in a CSS file under the .obsidian > snippets folder and then activate the snippet in the Obsidian settings under appearance. Have you done this steps?

@X012C
Copy link

X012C commented Aug 19, 2024

image I am new to obsidian. I loaded the CSS in the default theme but it didn't take effect. I don't know which step I missed. I hope to get help.

@X012C You have to save the CSS code in a CSS file under the .obsidian > snippets folder and then activate the snippet in the Obsidian settings under appearance. Have you done this steps?

image
I should be done.

@KillyMXI
Copy link
Author

image I am new to obsidian. I loaded the CSS in the default theme but it didn't take effect. I don't know which step I missed. I hope to get help.

@X012C the issue is that this is intended to work with markdown lists, and you're showing just intended text instead of a list.

Refer to https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Lists.

While Obsidian makes indented text to behave somewhat similar to lists (with indentation guides and folding), I don't think it is good to use.

@X012C
Copy link

X012C commented Aug 19, 2024

image I am new to obsidian. I loaded the CSS in the default theme but it didn't take effect. I don't know which step I missed. I hope to get help.

@X012C the issue is that this is intended to work with markdown lists, and you're showing just intended text instead of a list.

Refer to https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Lists.

While Obsidian makes indented text to behave somewhat similar to lists (with indentation guides and folding), I don't think it is good to use.

I use a translation tool, so there may be some discrepancies in communication. I tried to use the style of md lists in the address you provided, but it didn't work?
image

@KillyMXI
Copy link
Author

@X012C according to your screenshot, active list items highlight is working as expected.

If you need list threading - you have to use different CSS file. There are 4 of them in this Gist.

Use the "Download ZIP" button on the top right of this page to get all files at once.

@X012C
Copy link

X012C commented Aug 20, 2024

@X012C according to your screenshot, active list items highlight is working as expected.

If you need list threading - you have to use different CSS file. There are 4 of them in this Gist.

Use the "Download ZIP" button on the top right of this page to get all files at once.

It worked successfully, thanks for your help.

@dianedef
Copy link

dianedef commented Aug 21, 2024

This is splendid, and great for focus. Thanks a ton!
Edit 1 : Oh and BTW, it would be amazing to have all of these snippets into a plugin where we could maybe toggle hover, colors, and stuff... If you feel like it one day:)
Edit 2 : Oh you can configure stuff with the plugin Style Settings! Great =D

@muhirwa45
Copy link

Great job 👍
How I can i change color of bullet threading as one color (such light blue) instead of different color in editing, preview and reading mode?. Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment