Anki Forums

Editing Anki CSS/html

Just wondering if there have ever been requests or discussion or desire to see file based html cards. My wish list is to be able to use my favroite editor with syntax checking, linting, highlighting, undo etc while editing cards. I feel cramped up in the Anki editor. I do realize there are plugins but they also feel awkward both for editing and git integration. Since I have some complicated cards (4 cards with front and back) making changes to all cards is also inefficient and error-prone within Anki. Is the card html stored in Anki for performance reasons? Couln’t Anki one day just leave the card editing to other tools?

My other wishlist (that I know may never happen) is that the DOM is more consistent between the desktop and mobile versions. I realize there must be a reason for things the way they are… But it seems strange to me to see on desktop <body .card> but on mobile it is <body .card>. I’v finally got some nice grid and flex-based cards. But it took a while to realize that the mobile DOM being different was causing me some issues.

Hi Boyd!

For the creation and maintenance of multi-card templates I suggest using Asset Manager.
This addon solves the problem of having to edit the code of individual card templates.

But I agree, some external editor support would be nice to have.
The inconsistency between different clients can definitely be hindering. If you’re writing mobile-first for AnkiDroid, you’ll eventually realize that your template will not function properly on AnkiMobile, because it doesn’t rebuild its DOM every time, like AnkiDroid does. Still trying to figure out how to tackle this the best way.

@hengiesel, I’m wondering how you tackle complex card templates. Do you use an external editor in your workflow? I use Sublime (+ your editor in Asset Manager) for longer scripts, but I still need to copy it into the card editor from time to time to see if it works.

@boydkelly
I think just the ability to open templates in external editors would not improve the experience that much, because there’s still the issue of repeating components in templates. You say you have 4 cards, but now imagine that would be 20+ templates which are mostly similar except for small differences. Making a change to one, would mean you have to change it for all 20+.

Regarding the differences between Desktop and Mobile, that’s because Anki and AnkiDroid are developed by different teams, and now to warrant breaking backwards compatibility, you’d better have a good reason. However the future does bode well here. In the future, AnkiDesktop, AnkiDroid and AnkiMobile (on iOS) are gonna share more and more components, because AnkiDesktop already has a “backend library” which can/is also be used by AnkiDroid.

@kleinerpirat
Anki does not rebuild the DOM for efficiency purposes. Having to reload MathJax, jQuery libraries, etc. on every single card is pretty wasteful. In the future AnkiDroid will also probably head that way.
A strategy to avoid running code too many times is “guards”, where you have a variable, which checks, whether a specific code was already run:

// globally
if (!globalThis.myCodeIntialized) {
    // run my code
    globalThis.myCodeInitialized = true;
}

// or for specific HTML elements
if (!htmlElement.hasAttribute("has-myCode")) {
    // setup htmlElement
    htmlElement.setAttribute("has-myCode", "");
}

When I design a new card type, I also typically start in an external editor, and a browser window. You can test your template in multiple browsers, to make it more likely that it looks good on all platforms.

Besides that, the same things that are true for Web development as are true for Anki templates: Prefer CSS over JS for styling, Keep your HTML simply, etc.

3 Likes

Just learned about your add-on and it looks like a great workaround. But is there any reason why Anki couldn’t have a global style sheet and HTML header? I haven’t looked into that part of Anki and am not a frontend guy in general, but at a first glance it seems as it wouldn’t be hard to implement without breaking backwards compatibility.
I’m asking you because I can imagine you have already considered something like this.

I don’t think there’s a reason why it couldn’t have it, but there’s always that maintenance burden. When implementing a solution, it would always be nice if it can cover all cases. Like having a global HTML header would be nice, but how about a global HTML footer as well? What if a user wants to make small changes for specific templates? We’d quickly be back at the start, just with more complexity added.

My dream solution would be to be able to define a set of components using a library like Svelte, and have templates just include the externally defined components as it needs. Svelte would be perfectly suited for Anki templates, because it wouldn’t incur any overhead while viewing the cards, because it compiles down to Vanilla-HTML+CSS+JS. And in fact, Svelte is already used by Anki internally. Anki could then store the components defined in Svelte, but also store the compiled output.

So while this solution sounds nice in my head - and in fact my Asset Manager is a little bit modelled after this idea - how it would turn out in practice is a different question. Also it would cause major disturbance in the Anki world, so it would have to be really worth the hassle.

1 Like

Thanks Henrik for the little glance into the future!

With the next destop version you bring this paradigm to the editor as well, so it’s time for me to get used to it and learn some proper JS.

Now I know which direction to take, thanks!

I could see the support questions about badly formatted Svelte templates triple or more here. For most normal users, I think a WYSIWYG is the best way to go.

Very true :sweat_smile:

Anki was created in 2006, back when web development was much simpler, and many people had private web sites, for which they hacked some HTML+CSS+JS together, just to make it work, and were happy with it.

Now in 2020, web development is much more complicated, and users tend to not be happy, just with some hacked together card templates. At the same time, people are even less comfortable with the idea of writing HTML+CSS+JS themselves.

So while your idea, @khs, tries to win back those users, who might feel overwhelmed by the “Coding” component of Anki, a solution with Svelte would somewhat completely abandon those users, but help developers to create powerful templates (which then might be shared with other Anki users, who could benefit from theme), but were constrained before.

I think both viewpoints are valid and it really depends on which direction Anki wants to head into.

Thanks for the suggestion! I didn’t see that plugin or realize all its functionality. Just checking it out now. Nice to see the rest of the feedback here too!

2 Likes

Thanks for the answer.

I don’t see how that’s a problem since users would still be able to overwrite any behaviour on the template level.
It seems like an easy gain to me, but maybe I just don’t have enough insight.

@boydkelly, sorry for hijacking your topic. :wink:

If the templates have a WYSIWUG usage model, yes then great. If this leads to mistakes like missing semicolons in usage (CSS), then it’s not great.

I give you an example, if the user could select a specific template that handles multiple answers and pick one by just adding field content, then this is great. If the usage is that the end user needs to create fields and know the exact syntax, then it’s not so good.

The idea of professionalizing template development with Svelte sounds intriguing. It might attract a lot of high-skill developers and push things on another level.

On the other hand, Anki might lose a bit of its charm that brought people like me here in the first place: that if-you-can-think-of-it-you-can-do-it feeling :smiley:

Any way it goes, it’s nice that we’re discussing this here. I’m curious what Damien and the other devs think about this dream of yours.

(also sorry for the hijack @boydkelly :sweat_smile:
I hope you’ll find as much use in Asset Manager as I did)

@Rumo Or maybe I’m just thinking of the wrong thing :slight_smile:
I would have imagined it as some text field, let’s say in the main settings, which contains HTML, similiar to a note field, and then in the template, you could include it like {{GlobalAnkiHeader}}.

There’s a actually a secret feature in the Anki codebase, that is kinda like this. You can write to HTML to mw.col.conf["reviewExtra"], and it will be added to the template in the reviewer. I guess it qualifies more as a footer, because it is under the main qa section, but it could also contain JS to insert HTML elements anywhere. You could also use it to define a <style></style> section and have global CSS. However it only works on Desktop Anki.

@kleinerpirat I don’t even think Svelte is that complicated, especially compared to libraries like React, or Vue, or even trying to organize your code in plain JavaScript. In the end, it all feels very vanilla. If you have some spare time, you can try out the tutorial which is very well done. I think everybody who’s familiar with HTML+CSS+JS already, can easily pick it up.

All things aside, I think the power tools to create good templates is just one side of the coin. The other side would be a good platform to share templates with other people.

2 Likes

Re: global styling/scripts, the main reason reviewExtra is not exposed at the moment is because it could lead to cards that look a certain way when used in the collection, but look different when exported, which may be surprising. Adding a checkbox in the card layout screen to show without global styling might help to reduce the impact of this, but it’s still likely to cause more “why doesn’t Anki do what I expect” questions.

In the long run, some sort of styling/functionality add-ons in css/js might be nice. Currently deck authors bake their styling and functionality into their templates, which is painful for them to implement, and painful when they do things like accidentally hide fields on mobile devices, turn the foreground and background colours the same in night mode, and so on. If the styling and functionality were distributed and updatable separately in separate files, it could potentially make it easier to address such issues centrally. It’s adding extra complexity though, and implementing it well is a fair amount of work.

1 Like