Cssclasses for canvas-cards

What I’m trying to do

Inspired by canvas-candy, I’d like to create some nice CSS-enhancements for my canvasses.
I want to use the ‘cssclass’ keyword in frontmatter to be able to add formats to individual cards i.e. to create post-it like cards.

Things I have tried

here’s my CSS-snippet (example):

/* --- Standard Post-It --- */
.canvas-node-container:has(.cc-postit) {
    text-align: center;
    border-radius: 5px;
    border-width: 1px;
    background-color: antiquewhite;
    box-shadow: 0 8px 19px -13px rgba(0, 0, 0, .56), 0 4px 25px 0 rgba(0, 0, 0, .12), 0 8px 10px -5px rgba(0, 0, 0, .2);
}

Works nicely, BUT the first line is not at the top of the card.
It looks as if the space the frontmatter takes is not ignored:
image
image

Is there a way how I can make sure that the text is aligned to the top of the card?

OK, so here’s what I came up with:

.cc-postit > .markdown-preview-section > div:first-child {
  margin-top: calc(var(--line-height) * -16px) !important;
}

(depending on what theme or Obsidian version you have, you might want to replace --line-height with --line-height-normal .

Result (from left changed to right):

Looks good!
I tried by adding your code as a new entry in the CSS, works fine.

But - it seems as if I would have to create a similar code for each css-snippet I have defined (i.e. different post-it-cards with different colors (post-it-y, post-it-b etc.).

Would I have to create a

.cc-postit-y > .markdown-preview-section > div:first-child {
  margin-top: calc(var(--line-height) * -16px) !important;
}
.cc-postit-b > .markdown-preview-section > div:first-child {
  margin-top: calc(var(--line-height) * -16px) !important;
}

for each, or ist there a more elegant way?

What means ‘div:first-child’?

Thank you for your support!

Stefan

1 Like

Fret not, as there sure is a more generic way :sunglasses:

[class*="cc-postit"] > .markdown-preview-section > div:first-child {
    margin-top: calc(var(--line-height) * -16px) !important;
}

The above says that it should target any note whose CSS class contains (*=) the string “cc-postit”, whether it’s “cc-postit-x” or “mycc-postit-test” and whatnot.

Or you can make your own prefix like zz and target everything with that prefix using the starts with (^=) operator, like [class^="zz"] > ...


Heck, you can even put the whole calculation-shebang inside a global CSS variable and reuse it anywhere without retyping it:

/* adjust text margin & timestamp color here */
:root, body, .view-content {
  --canvas-embed-margin: calc(var(--line-height) * -16px) !important;
}

[class*="cc-postit"] > .markdown-preview-section > div:first-child {
  margin-top: var(--canvas-embed-margin)
}

Wow. still so much to learn about CCS.
But it’s amazing, I love it.

Thank you so much for explaning this to me!

Interestingly, this code does the job:

[class*="cc-"] > .markdown-preview-section > div:first-child {
    margin-top: var(--canvas-embed-margin)
  }

this one does not:

[class^="cc-"] > .markdown-preview-section > div:first-child {
    margin-top: var(--canvas-embed-margin)
  }

Since i can’t be 100% sure that there is nowhere any class that conains ‘cc-’ somewhere in the middle, I’d prefer to restrict the command to only those classes which exactly begin with ‘cc-’

Any idea, what could be wrong?

2 Likes

Indeed, it seems that it doesn’t work because the canvas card itself has multiple other classes defined by Obsidian, themes & plugins, making the cc- class never the first one, hence why ^= won’t work in this particular case.

So you’re left with just the *= (contains) operator, but you probably have to use your own made up matching keyword or prefix (which can obviously be longer than a few letters), something that you’ll be sure it won’t be used by any other class :wink:

No problem, I can do that.

As usual, the appetite comes while eating (or so goes a German saying), so I’d like to use a different Font for my post-its.
ChatGPT tries to convince me, I should use a statement like this:

[class*="cc-postit"] > .markdown-preview-section > div:first-child {
    margin-top: var(--canvas-embed-margin)
   font-family: 'Kalam', sans-serif;
    src: url('c:/Users/Stefa/Downloads/Kalam/Kalam-Regular.ttf') format('truetype'); 
  }

But - it doesn’t work.
What weird: I have ‘Kalam’ installed on my Windows 11 machine, but I can’t find the file in c:/windows/fonts.
That’s why I downloaded it from Google.

If you have the font installed on your computer and you can use it in other apps, then try using just this line (assuming this is what the font is named in other apps as well) with no src and stuff:

font-family: 'Kalam';

If that doesn’t work, then unfortunately Obsidian doesn’t allow using custom fonts based on URLs or font location either, so instead you have to embed fonts in the CSS file as binary base64 data.

There’s a page on Obsidian’s documentation detailing the process (apparently ChatGPT didn’t read the Obsidian docs :sweat_smile:):

Unfortunately, the simple version doesn’t work either.

I’ll go and check out the documentation.

Thank’s a lot for your helpful tips! :pray:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.