Want a multi-level dropdown menu INSIDE your notes? You can! I built one :)

Hi there,

I achieved to create a multi level CSS dropdown menu inside a note of mine.There was one thing that didn’t quite work and @sailKite fixed that for me (Thanks!) so now it is fully working.

@sailKite made this nice gif to show that it is working:


I will attach a Menu Test.md and the CSS file. Inside the Menu Test.md you will find more explanation on how to use it. You will need to put in your own links in the proper format (Obsidian URL of your note) so I suggest you read the note carefully to make it work in your own vault.

You will need some understanding of basic HTML, you can change the CSS if you want but please, just change colors and simple stuff that doesn’t break the menu, unless you are a CSS wizard and know exactly what you are doing.

The CSS code is also inside the Test Menu.md as pure text. You may copy and paste that in your own file if you want or use the attached menu1.css file.

Menu Test.md (7.1 KB)
menu1.css (2.8 KB)

Have fun with it :grin:


This is kind of a fun experiment. A few things:

  • If the CSS file is meant to be a drop-in snippet, you probably don’t want to include the html, body block of styles, as those could interfere with the theme.

  • Where does the class el-nav enter in? Does that come from the way Obsidian renders things?

  • What purpose do the enclosing <html></html> tags serve in the MD file? Doesn’t this introduce a secondary HTML block inside the page’s BODY, which not where such a block should be?


1 Like

Another thing occurred to me. Since you’re introducing raw HTML there’s no need to introduce the cssclass: menu1 frontmatter. Instead put it where it applies <nav class="menu1">

1 Like

It seems to me a construct like the following would make much more sense inside a Markdown document instead of the full-blown HTML:

<nav class="menu1">

   + [[Item 1]]
   + [[Item 2]]
      + [[Sub Item 2.1]]
         + [[Sub-Sub Item 2.1.1]]
      + [[Sub Item 2.2]]
   + [[Item 3]]


Note 1: The blank line after the opening tag and the one before the close tag allow the Markdown to be rendered, thanks to CommonMark. Just make sure the lines contain no content (i.e. no spaces), because that will throw off the rendering.

Note 2: Using this format should allow you use Markdown or Wikilinks style links instead of the more-difficult-to-get-right HTML A tags.

Note 3: According to the Element inspector, Obsidian unexpectedly renders the above (in preview mode) as shown below. To get the CSS to work correctly with this will require some gnarly specifiers. (What is the syntax to specify a div containing a nav preceding a div containing a ul?) If you can work those out, though, this format would be much more user friendly.

   <nav class="menu1"></nav>

Novice question: Does the raw HTML get rid of the extra div wrapping? The way HTML is treated in Live Preview was kind of surprising to me.

Each block of raw HTML gets wrapped in a simple div.

For example:

<p>Paragraph 1</p>
<p>Paragraph 2</p>

gets rendered as

   <p>Paragraph 1</p>
   <p>Paragraph 2</p>

If instead the raw HTML was written as

<p>Paragraph 1</p>

<p>Paragraph 2</p>

you’ll get two div blocks

   <p>Paragraph 1</p>
   <p>Paragraph 2</p>

What I did not expect is that when Obsidian renders the Markdown inside the two raw HTML blocks using the trick above, it treats it as a block outside of the HTML. Perhaps there’s a reason for this, but it feels like a bug to me.

If the second one is a span instead of a paragraph, then the behavior in Live Preview is completely different between the two, but in Reading Mode they are much more similar (the span is just wrapped in a paragraph tag). In Source Mode they look identical in the Element inspector, but different again from both LP and Reading. Interesting!

EDIT2: I wonder what of the classes added to the various divs is from CodeMirror and what is particular to Obsidian, but I do not wonder sufficiently to go find a CodeMirror instance with HyperMD and find out.

At the level we’re discussing here, we’re pretty much passed all the CodeMirror/Obsidian classes and are down to just simple HTML tags.

I submitted a bug report about the Markdown not getting rendered correctly inside of HTML tags. The reply I received is that Obsidian does not support doing that. I had hoped to work around that shortcoming by applying CSS to the odd output it does generate, but it does not appear that CSS offers the necessary selectors to match this structure. I guess it’s back to a fully HTML menu.

Well, I guess your question from several posts ago is answered! I know that Obsidian does some HTML sanitization, and also I believe that the commonmark spec does say to leave the contents of HTML tags alone? That part of the spec was confusing to me, though. (Why was I reading the commonmark spec? Good question. Confusing linter errors/behavior, difficulty stopping reading something once I have started, suboptimal prioritization of what to do with my time, curiosity.)
And while it is nice that Source Mode in Obsidian has some support for HTML writing (it seemed to be coloring things red when my tags were mismatched), I think I would want an editor that helped me more to get my HTML correct (and properly accessible to screenreaders and …) if I were writing lots of it.

I didn’t get a message there was a reply to my post, I happened to see it just now!

I am not focused enough right now to answer your questions, becauseI am about to leave for the day. But I will come back to it :slight_smile:

I knew that markup inside hmtl doesn’t (always) work. You have to at least have one empty line between html and markup, then it sometimes works. It was the reason I tried an oldschool html/css menu that I used to use back in the 90’s/2000’s. And it works, with a little bit of trickery. Since I will most likely include it on pages I want to use it on, I think that is fine. Perhaps double html tags get stripped from a page anyway by Obsidian? I haven’t encountered any problems with it yet.

I am building an in-note “webpage” of sorts…
The only thing I would like to figure out is how I can have something simulating the old html frames. I know that ![[somelink]] includes a note inside another note.

But what I can’t figure out, is how to write a link in my menu, that would open (or actually include) a note inside the note that the menu is in (or included in).

Would you know if that is at all possible ?

I can see opening other notes and jumping to other sections of the current note, but not a way to direct those clicks to open inside a section of the current note (into an IFRAME, say) without some programming to intercept those click events.

Okay, that is clear :slight_smile:

Then I need to change my approach to this, to avoid the whole idea becoming very cumbsersome.

  • I could build one long note and link to the sections. I could use CSS to render stuff invisible unless clicked on a link to show it. Done that before with 1-page websites. Advantage: less creation of files, much cleaner in the file explorer. Disanvantage: not possible to have different footers or headers unless I create some pretty complex css for it to behave that way.
  • I could make a “frame-note” for every page, that holds all the includes and images for that page and then link to the frame-note. It would load a different note/page, but only the included content would change since their frame comes from a template and is there for identical. Advantage: possible to have different headers and footers for each “page”. Disadvantage: lots of clutter int he File explorer, with folders to hold every page and its “includes” or otherwise it would become very difficult to find the right header/footer/content for a page.

I’m going to sleep on this haha