obsidian-tasks-group / obsidian-tasks

Task management for the Obsidian knowledge base.
https://publish.obsidian.md/tasks/
MIT License
2.49k stars 231 forks source link

Ability to change task field emojis (e.g. with font awesome icons) in rendered view #1737

Open tobei opened 1 year ago

tobei commented 1 year ago

⚠️ Please check that this feature request hasn't been suggested before.

🔖 Feature description

While using the appropriate one character emoji code as field delimiter is both a good idea for parsing and for rendering, the lack of ability to customize those icons (that comes with the font) to fit a specific theme or consistency is a bit annoying. I'd prefer to be able to choose how they display in the rendered view through css for example.

✔️ Solution

If the meta-datas (like due date, recurrence etc) would come as separate element with appropriate class and no emoji or icon, one could supply through styling whatever icon they see fit by just adding a ::pre pseudo class with content they like. This could for example default to the current emojis so the rendering stays consistant.

I would like for example to be able to use some font-awesome flat monochromatic icons that would fit the sobriety of my notes much more than the current eye-popping colorful emoji icons.

It would just be in the rendered/printed view.

❓ Alternatives

Just be able to choose image/font/iconset in the plugin configuration for each of those elements.

📝 Additional Context

No response

claremacrae commented 1 year ago

If I understand your request correctly, this would become possible when https://github.com/obsidian-tasks-group/obsidian-tasks/pull/1519 is finished. It turned out to be a very large volume of work.

tobei commented 1 year ago

If I understand your request correctly, this would become possible when #1519 is finished. It turned out to be a very large volume of work.

I saw that PR when i browsed but it seems that the emoji character stays part of the task field, so i don't know if css has the ability to strip and replace it with something entirely different. Maybe that emoji should stay as it's own separate element or pre to the actual field so it can be stripped or replaced with any image or illustration one wants. In my case i find fontawesome and other iconset to be sober and consistant, so i would replace the current emoji character with another character chosen in the fontawesome font.

Alternative would be to use ::first-letter class to make that emoji character disappear and then add pre element with the appropriate font and content to render the replacement icon, it's messy but in theory... could work

TomWol commented 1 year ago

I have been testing in that PR and been using the ::first-letter CSS pseudo-class to, in my case, tweak the Unicode/emoji characters. For example, fixing the vertical alignment of the recurrence character to align better with the lowercase every week text next to it. That does work, provided you define the span containing the emoji as a block level element - in my layout I use display: inline-block.

You could do something like what is discussed here in combination with that: color: transparent in the ::first-letter pseudo-class and using a ::before or ::after pseudo-class.

I have mentioned putting the Unicode characters in a separate span in the discussion for that PR, but it has not been picked up by the developer at this point. The above mentioned workaround would definitely work.

In the long run, being able to alter the icons the way you describe would be great. But as long as there's a way to do it if I really want to, I'm pretty happy as it is.

tobei commented 1 year ago

I downloaded the last version of Tasks and it seems like the emoji is rendered as second letter of their respective span element. There is a space before each that seems to be a reminder of the task parsing but shouldn't be part of the data. Alignment of items should be left to CSS and be trimmed of initial and ending white spaces. So for now the ::first-letter is a space and there is no nth-letter(2) to get around that

claremacrae commented 1 year ago

@esm7 FYI… is this anything that you could help with, please?

TomWol commented 1 year ago

I downloaded the last version of Tasks and it seems like the emoji is rendered as second letter of their respective span element. There is a space before each that seems to be a reminder of the task parsing but shouldn't be part of the data. Alignment of items should be left to CSS and be trimmed of initial and ending white spaces. So for now the ::first-letter is a space and there is no nth-letter(2) to get around that

It does look that way in the Developer Tools, and it might even be the case (I do not contribute to the code, I just use Tasks), but everything is working fine on my side using the ::first-letter pseudo-element in Tasks 3.0.0 (the latest version). I have targeted every task icon available and every one of them except the edit button can be targeted this way (the edit button is not a Unicode font character, it needs to be targeted differently).

As I mentioned in my previous post, ::first-letter only works on block-level elements, so you need to make sure the innermost span directly surrounding the text is redefined as such, for example:

span.task-due span {
    display: inline-block;
}

That second span is the key here, without it it will not work. Then you can use the ::first-letter element, but again, you need to target the inner span:

span.task-due span::first-letter {
    font-size: 10px;
}

Can you check if that helps with your problem? If not, feel free to post the code that is not working and I will try it out.

esm7 commented 1 year ago

@esm7 FYI… is this anything that you could help with, please?

Sorry for the delay, I was almost completely unavailable in the past 4 days. From a first glance I'm unsure this is doable with pure CSS, but I'll give this more thorough attention in the next few days. Maybe it's worth adding additional spans that will make this possible, if it's not currently.

esm7 commented 1 year ago

So I basically see two options:

  1. Remove the preceding space from task components and use pure CSS to express this spacing, allowing ::first-letter to be used to target the various emojis. Although technically easy, the reason I didn't do this in the first place is that I wanted the default (without custom CSS) rendering of tasks to be pixel-perfect compatible with how it was before my PR. I can try to imitate this with a CSS margin, but I'm unsure it will be pixel-perfect. Don't know if it matters -- @claremacrae your call. It is surely cleaner this way in the long run.
  2. Add an extra internal span for the various component symbols (the emojis), with or without eliminating the extra space. I'm wondering whether the extra complexity of the generated document is worth the flexibility gained here, given that ::first-letter gives most of the same flexibility if the space is removed. What do you all think? What are the use cases of an extra span except replacing/hiding the emoji?
claremacrae commented 1 year ago

Hi, thanks @esm7

  1. Remove the preceding space from task components and use pure CSS to express this spacing, allowing ::first-letter to be used to target the various emojis. Although technically easy, the reason I didn't do this in the first place is that I wanted the default (without custom CSS) rendering of tasks to be pixel-perfect compatible with how it was before my PR.

At this point, I feel that 'cleaner' - for CSS writers and maybe for Tasks developers too - is more important than 'pixel perfect'.

@claremacrae your call. It is surely cleaner this way in the long run.

Excellent - please do it!

  1. Add an extra internal span for the various component symbols (the emojis), with or without eliminating the extra space. I'm wondering whether the extra complexity of the generated document is worth the flexibility gained here, given that ::first-letter gives most of the same flexibility if the space is removed. What do you all think? What are the use cases of an extra span except replacing/hiding the emoji?

As a non-CSS person I have found the nesting of spans to already be a bit confusing, so the fact that you have identified a nicer option than added more spans is music to my ears!

TomWol commented 1 year ago

I downloaded the last version of Tasks and it seems like the emoji is rendered as second letter of their respective span element. There is a space before each that seems to be a reminder of the task parsing but shouldn't be part of the data. Alignment of items should be left to CSS and be trimmed of initial and ending white spaces. So for now the ::first-letter is a space and there is no nth-letter(2) to get around that

It does look that way in the Developer Tools, and it might even be the case (I do not contribute to the code, I just use Tasks), but everything is working fine on my side using the ::first-letter pseudo-element in Tasks 3.0.0 (the latest version). I have targeted every task icon available and every one of them except the edit button can be targeted this way (the edit button is not a Unicode font character, it needs to be targeted differently).

As I mentioned in my previous post, ::first-letter only works on block-level elements, so you need to make sure the innermost span directly surrounding the text is redefined as such, for example:

span.task-due span {
    display: inline-block;
}

That second span is the key here, without it it will not work. Then you can use the ::first-letter element, but again, you need to target the inner span:

span.task-due span::first-letter {
    font-size: 10px;
}

Can you check if that helps with your problem? If not, feel free to post the code that is not working and I will try it out.

@esm7 @claremacrae I feel like my above post is not being noticed. The ::first-letter pseudo-element works fine with the space, as I mentioned, because a space isn't considered a letter. (EDIT: Apparently many punctuation and Unicode characters are considered letters, which is why it works fine on the icons.)

I made a JSFiddle here to demonstrate it working just fine, I'm using it to make the icon much larger here: https://jsfiddle.net/TomWollaert/oeg5vcnb/4/

claremacrae commented 1 year ago

@esm7 @claremacrae I feel like my above post is not being noticed. The ::first-letter pseudo-element works fine with the space, as I mentioned, because a space isn't considered a letter.

I made a JSFiddle here to demonstrate it working just fine, I'm using it to make the icon much larger here: https://jsfiddle.net/TomWollaert/oeg5vcnb/4/

Hi @TomWol - many thanks for (re-)pointing that out. The JSFiddle was really helpful.

esm7 commented 1 year ago

@TomWol sorry for misreading your previous comment, it's so awesome to know that it works! The ability to use CSS to change the emojis goes deep into the "I never would have considered possible" category, so I think it's highly worth adding to the Tasks Show and Tell.