Add CSS class for each level in a nested tag, to enable fine-grained CSS selection in edit and preview modes

Use case or problem

I’d like to add context-sensitive color to nested tags in both preview and edit mode.

It is possible to style non-nested tags by using a CSS selector such as this: (for a tag #project)

.cm-s-obsidian, .cm-s-obsidian

This works in both edit and preview mode.

HOWEVER this breaks down when nested tags are used. The nested tag #project/test-project-a is NOT colored by the above rule.

In preview mode the above renders as:

<a href="#project/test-project-a" class="tag" target="_blank" rel="noopener">#project/test-project-a</a>

This is easy to create a CSS selector for because we can just target the beginning of the string:


But we can’t do this in edit mode due to the way edit mode constructs the CSS classes.

This is because the editor embeds the entire tag name as a CSS class in edit mode. Typing the above tag in edit mode renders as the following in edit mode:

<span class="cm-hashtag cm-meta cm-hashtag-end cm-tag-projecttest-project-a">project/test-project-a</span>

As you can see, the only way to color this tag is to modify the CSS snippet every time a new project is created, to add a selector for cm-tag-projecttest-project-a.

Proposed solution

Add each component of a nested tag as a separate CSS class.

Given tag: #foo/bar/baz

Render this in edit mode:

<span class="cm-hashtag cm-meta cm-hashtag-end cm-tag-foo cm-tag-foo-bar cm-tag-foo-bar-baz">project/test-project-a</span>

Notice the tag is split into three separate classes, one for each nesting level. This allows easy selector definition for defining scoped colors in edit mode.

And in preview mode:

<a href="#project/test-project-a" class="tag tag-foo tag-foo-bar tag-foo-bar-baz" target="_blank" rel="noopener">#project/test-project-a</a>

Current workaround (optional)


Related feature requests (optional)

This question has come up several times in various places, for example:

Would something like this work for you in editor mode?


No but after a small bit of tinkering I DID get this to work.

It just needed a tiny smidge more specificity even with !important. ¯\_(ツ)_/¯

  background-color: var(--project-tag-background) !important;

:point_up_2:This now colors tags in both preview AND edit mode, with a single declaration covering both #project and #project/anything-here/and-more-here-is-fine-too!

I had completely forgotten about the wildcard selector, thanks!! :smiley: :beers:

1 Like