0

I want to write a custom CSS for the Obsidian editor. The element tree in question looks like this:

.markdown-embed
  .markdown-embed-title
  .markdown-embed-content
    .markdown-preview-view
      .markdown-preview-sizer
        div
          some content
        div
          some content
        div
          some content
        div
          some content

Basically, there's a bunch of nested classes, and then some divs containing text, headers, list and so on. I want to disable (set display: none;) the .markdown-embed-title and all headers in the third div, but only if the .markdown-embed-title is empty.

I suspect this should be possible using :empty and possibly :has() to check if the title is empty and :nth-child(3) to select only the third div. But so far I couldn't figure out how to do that.

For now, I'm able to select the title and all headers in all divs using the following CSS (I change the color instead of the visibility, everything that is red should be hidden later):

.markdown-embed-title {
  color: crimson;
}

.markdown-embed-content>.markdown-preview-view>.markdown-preview-sizer>div :is(h1, h2, h3, h4, h5, h6) {
  color: crimson;
}

This gives me this result:

enter image description here

So far so good. I thought I could now just select the third div by changing the selector before the headings to ...>div:nth-child(3). However, this doesn't work and all of the headers are now displayed in black.

I also thought I could incorporate the logic that headers should only be affected if the title is empty by changing the selector to .markdown-embed-content:has(+ .markdown-embed-title:empty())>..., basically checking if the sibling is empty. This too didn't work and no headings are affected.

What am I doing wrong?

Texfy
  • 27
  • 5

1 Answers1

2

It can be done with a couple of ways. I've made it colour the div red or yellow so you can see it being applied rather than using display: none but hopefully you can see how it works. The red one uses :has() and the yellow one uses the general sibling combinator. The latter is more supported.

.markdown-embed:has(.markdown-embed-title:empty) .markdown-preview-sizer div:nth-child(3) {
  background-color: red;
}

.markdown-embed .markdown-embed-title:empty~.markdown-embed-content .markdown-preview-sizer div:nth-child(3) {
  color: yellow;
}
Has a title
<div class="markdown-embed">
  <div class="markdown-embed-title">This is a Title</div>
  <div class="markdown-embed-content">
    <div class="markdown-preview-sizer">
      <div>Some content 1</div>
      <div>Some content 2</div>
      <div>Some content 3</div>
      <div>Some content 4</div>
    </div>
  </div>
</div>
<hr> No title
<div class="markdown-embed">
  <div class="markdown-embed-title"></div>
  <div class="markdown-embed-content">
    <div class="markdown-preview-sizer">
      <div>Some content 1</div>
      <div>Some content 2</div>
      <div>Some content 3</div>
      <div>Some content 4</div>
    </div>
  </div>
</div>
Adam
  • 5,495
  • 2
  • 7
  • 24
  • Thanks for the swift answer! That worked for me. Can you explain why it didn't work when I just added the `has()` and `nth-child()` to my code? I guess it has to do with the `>` between classes? – Texfy Dec 21 '22 at 17:10
  • It didn't work because .markdown-embed-content doesn't have .markdown-embed-title in it and if you fixed that, the adjacent sibling combinator would only work if the .markdown-embed-title appeared after .markdown-embed.content in your html – Adam Dec 21 '22 at 17:39
  • 1
    Ah okay, I didn't realize the sibling combinator would only work in one direction! Thanks! – Texfy Dec 22 '22 at 08:09