Hide or Truncate URLs in Editor using CSS?

Until the WYSWYG editor comes out, it seems we will have to live with URLs in the editor view, but some URLs are very long. For instance, here is the URL for a Chinese movie I recently needed to reference in a document:

https://zh.wikipedia.org/zh-tw/%E6%88%91%E4%B8%8D%E6%98%AF%E6%BD%98%E9%87%91%E8%8E%B2_(%E7%94%B5%E5%BD%B1)

Having this URL in my editor really interrupts the flow when I’m trying to read what I wrote. Without having to use a URL shortener of some kind, is there some way to use CSS that could hide this from view in the editor?

Ideally it would look something like this [I Am Not Madame Bovary](wikipedia.org) or [I Am Not Madame Bovary](🔗)

3 Likes

This is possible, I think, but I question the utility. If you need to modify the url for whatever reason (e.g. there’s extra characters on the end or something) how would you edit it?

Actually, I may have come up with something:

div:not(.CodeMirror-activeline) > .CodeMirror-line .cm-string.cm-url:not(.cm-formatting) {
    font-size: 0;
}
div:not(.CodeMirror-activeline) > .CodeMirror-line .cm-string.cm-url:not(.cm-formatting)::after {
    content: '🔗';
    font-size: 1rem;
}

When your cursor is on the active line, you’ll see the full URL (so you can edit it) and if it’s not the active line, it’s hidden with a single character (in this case 🔗) shown in its stead.

(Thanks to @Silver for exposing the active line with a CSS class :+1:)

26 Likes

Wow! This is amazing. I didn’t really know if it was possible or not to do this with CSS, so this is much more than I hoped for! Thanks.

2 Likes

Wonderful. Not sure, tho, how to insert or where to insert the code in css file. Where would I place it?

1 Like

It should work fine pasted anywhere in your obsidian.css file. Though it’s probably easiest right at the top or right at the bottom of the file

1 Like

Magician confirmed. You have broken people’s expectation as to what’s achievable by CSS! :laughing: :+1:

1 Like

CSS is great, you could even write CSS functions today.

Thanks @Silver, sometimes I break my own expectations :laughing:

What is this wizardry? :open_mouth:

@death.au , can you work the same magic to provide a way to hide the # symbol in headings? The change in font size is enough for me to know it’s a heading, and I use a lot of headings, and I don’t like seeing hundreds of # in my editor. Waiting with bated breath…

1 Like

Sorry to keep you hanging @cobblepot, but this should be what you need:

.CodeMirror-code > :not(.CodeMirror-activeline) .cm-formatting-header {
  display:none;
}
2 Likes

No problem and many thanks, @death.au! I tried combining your two solutions to achieve two other looks but my css isn’t up to the task, apparently. If you are so inclined and have the time, I would love to see solutions for these (no obligation, obviously):

  1. Remove all # symbols from headings but also add a single § to all headers - just one, regardless of heading level.
  2. Remove all # symbols from headings but also add a single § to first-level headings only–other headings get nothing.

This is actually pretty easy and simple to do.

In this example you’ll get H1 before the header, so just change content: to content: "§ ".

2 Likes

I’ll also add that if you’re looking to do this in the editor, the selectors will be .cm-header-1::before for the H1 or .cm-header::before for all headers.

So, in summary:

.CodeMirror-code > :not(.CodeMirror-activeline) .cm-formatting-header {
  display:none;
}
.CodeMirror-code > :not(.CodeMirror-activeline) .cm-header::before {
  content: "§ ";
}

(and if you want just H1s instead of all headers, use .cm-header-1 instead of .cm-header)
This is just for the editor, and untested

2 Likes

hey @death.au thanks for that great code, I used your code as the foundations for this css hack I made

# replaced by §

This is the project I’m working on based on your code:

Org-sidian Bullets ◉ Instead Of # For Headers (Inspired by org-mode)

There’s a strange bug I can’t seem to fix, could you please take a quick look at it


Some headings get the symbols repeated in a strange way

It happens to normal text sometimes

but the bug I can always replicate is when I do something like this:

I create a normal heading

# [[test heading]]

Instead of displaying this
§ [[test heading]]

it displays this
§ [[§ test heading§ ]]

I’m using your code exactly as is, with a blank obsdian.css to make sure nothing from my theme interferes.


I would really appreciate any help, since my css hack fully depends on this.

Thank you!

Without looking too deeply into it, I think it’s probably because a heading with a link gets split up into multiple spans with formatting, etc.
You might try adding :first-child to the selector to see if that helps.

1 Like

Thanks for the suggestion @death.au, really appreciate it , unfortunately I wasn’t able to use :first-child without breaking things.

If you got a change would you be willing to help me take a quick look to see what’s wrong

I tried to use something like nth-child() but wasn’t able to make it work either

Here’s the code, it’s pretty much the same as your (plus margins) I just define it in the same way for all the remaining heading sizes

.CodeMirror-code > :not(.CodeMirror-activeline) .cm-formatting-header {
  display:none;
  }
  /* heading 1 */
  .CodeMirror-code > :not(.CodeMirror-activeline) .cm-header-1::before {
  margin-right: 8px;
  content: "◉";
  }
  /* heading 2 */
  .CodeMirror-code > :not(.CodeMirror-activeline) .cm-header-2::before {
  margin-left: 10px;
  margin-right: 8px;
  content: "○";
  }

I understand you are busy, so no worries if you can’t, but it would mean a lot if you got a chance to take look at it.
Thanks!

Sorry it took me a while to get around to this, @santi but I did manage to come up with a solution:

.CodeMirror-code> :not(.CodeMirror-activeline) .cm-formatting-header {
  display: none;
}

/* heading 1 */
.CodeMirror-code> :not(.CodeMirror-activeline) .cm-formatting-header+.cm-header-1::before {
  margin-right: 8px;
  content: "◉";
}

/* heading 2 */
.CodeMirror-code> :not(.CodeMirror-activeline) .cm-formatting-header+.cm-header-2::before {
  margin-left: 10px;
  margin-right: 8px;
  content: "○";
}

The trick is .cm-formatting-header+.cm-header-1 so it only targets the .cm-header-1 span that comes directly after the .cm-formatting-header span. Since headers (usually) only have their formatting symbol at the start, this should be fine.

Though the above won’t work with Setext-Style headers (the other style of markdown headers) where you put the formatting underneath… for example:

This is a h1
===

This is a h2
---

But In that case, the first-child thing works! So, for completeness sake:

/* heading 1 */
.CodeMirror-code> :not(.CodeMirror-activeline) .cm-formatting-header+.cm-header-1::before,
.CodeMirror-code> :not(.CodeMirror-activeline) .cm-header-1:first-child::before {
  margin-right: 8px;
  content: "◉";
}

/* heading 2 */
.CodeMirror-code> :not(.CodeMirror-activeline) .cm-formatting-header+.cm-header-2::before,
.CodeMirror-code> :not(.CodeMirror-activeline) .cm-header-1:first-child::before {
  margin-left: 10px;
  margin-right: 8px;
  content: "○";
}

… It’s possible I spend too much time working on things that really don’t matter. Especially since Obsidian’s default theme seems to not like links in Setex-style headers:
image

1 Like

Thank you so much @death.au I really appreciate it, it works perfectly. I get you, I don’t use “Setex-style headers” but still thanks for including code for it!

I’ll update the code here if anyone else is interested in the full code for all headers

Org-sidian Bullets ◉ Instead Of # For Headers (Inspired by org-mode)

Thanks once again @death.au I was really stuck with it, it means a lot!

1 Like