There’s some work I would like to do using CSS transitions (for instance, something like a card flip, but these would involve toggling class names of elements in the existing DOM. What I’ve seen of the TW model is to always regenerate HTML and never alter the DOM. Does TW have the capability to find HTML elements and add or remove classes on them?
https://tid.li/tw5/plugins-2019.html#%24%3A%2Fplugins%2Ftelmiger%2FFlippyCards
https://tid.li/tw5/test/flippy.html
@telmiger Flippy cards may be of some help.
Thank you. I’ll dig in and see how the transitions are triggered.
I figured that this must exist, although my search was related to transitions, not specifically flipping cards, which is precisely what I want!
I may not understand this but a new stylesheet listed at the end of the stylesheets will override previously defined CSS. Typically CSS is applied after all the HTML work. So you can redefine any existing CSS as desired. As long as you can identify the right selector(s). Some do this through the browser tools inspect.
Feel free to ignore this, but if you want to know, the article I mentioned has a demo at sandpack-project - CodeSandbox. You can see the card turn over when you click the flip
button. The code that does this is in the button handler, and it looks like this:
front.classList.toggle('flipped')
back.classList.toggle('flipped')
This simply adds the CSS classname “flipped” when it’s not already there, and removes it when it is. front
and back
are identically sized-and-placed HTML DIV elements, and the magic happens in the CSS:
.cardFront, .cardBack {transition: transform 0.5s;}
.cardFront {transform: rotateY(0deg);}
.cardFront.flipped {transform: rotateY(-180deg);}
.cardBack {transform: rotateY(180deg);}
.cardBack.flipped {transform: rotateY(0deg);}
When the flipped
class is added to front
, it changes from rotateY(0deg)
to rotateY(-180deg)
. When flipped
is removed, it changes back to rotateY(0deg)
. In both cases, there is a 0.5
second transition. (You can slow this down by changing the speed on line 34
to, say, 3.0s
– it demonstrates the effect more clearly.)
This is the mechanism I was hoping to take advantage of. Looking at @telmiger’s Flippy Cards, it seems as though this is not necessary. My understanding was that the changed document is rebuilt and I would have thought that this would mean that such animations wouldn’t run. But the code, so far as I’ve read, seems to do the entirely normal HTML building I otherwise expect, but the transitions still run so I’m either misunderstanding CSS transitions or the Tiddlywiki model, or, quite possibly, both.
I’m hoping someone can pop up to explain what I’m missing, but it looks like @arunnbabu81 has supplied a model I can copy with or without understanding, or perhaps just use intact.
Some background that might be helpful:
In TiddlyWiki when you use an HTML tag, it is parsed by the wikitext parser and handled by the $element widget (which does not have any direct user affordances). The $element widget then creates the required DOM node. This is why you can use variables, text references and filtered transclusions for indirect assignment of the value of an HTML element’s attributes, just as you can with other widgets. When the value of an indirectly assigned attribute changes due to the TW refresh cycle being triggered by tiddler changes, the widget updates the DOM node’s corresponding attribute without destroying the DOM node or its children.
However, if a widget wrapped around the HTML tag needs to destroy and recreate itself as part of the TW refresh cycle, such as the $let widget when the value of a variable it assigns changes, then the contents of that surrounding widget are destroyed and recreated. In such a situation you will not get CSS animations as the DOM node is destroyed and re-created.

When the
flipped
class is added tofront
, it changes fromrotateY(0deg)
torotateY(-180deg)
. Whenflipped
is removed, it changes back torotateY(0deg)
. In both cases, there is a0.5
second transition. (You can slow this down by changing the speed on line34
to, say,3.0s
– it demonstrates the effect more clearly.)
In TiddlyWiki an equivalent to that technique would look something like this:
<div class={{{ cardFront [[statetiddler]get[text]match[flipped]] :and[join[ ]] }}}>
<!--content here-->
</div>
Along with a button somewhere (which could be the card div itself using the $button widget to create the div) that toggles the value of the state tiddler between flipped and blank. Clicking the button would change the value of the state tiddler, which in turn would change the class assigned to the div.

Looking at @telmiger’s Flippy Cards, it seems as though this is not necessary. My understanding was that the changed document is rebuilt and I would have thought that this would mean that such animations wouldn’t run.
I have only had a cursory glance at this but it seems like it uses the checked state of a checkbox along with an adjacent CSS selector to flip the card. As such, this is a pure CSS/HTML implementation that does not involve changes to any tiddlers and does not trigger the TW refresh process. Therefore the question of DOM elements being re-created never even arises. The downside with this approach is that if other user interaction triggers a refresh in the wiki, the state of the checkbox (and this the card) might not be preserved across the refresh cycle.

When the value of an indirectly assigned attribute changes due to the TW refresh cycle being triggered by tiddler changes, the widget updates the DOM node’s corresponding attribute without destroying the DOM node or its children.
Ah, then I did entirely misunderstand part of the rendering cycle. This is very useful information; thank you.

However, if a widget wrapped around the HTML tag needs to destroy and recreate itself as part of the TW refresh cycle, such as the $let widget when the value of a variable it assigns changes, then the contents of that surrounding widget are destroyed and recreated.
This is what I thought was universal. It’s nice to know that it’s not. It offers some useful possibilities.

The downside with this approach is that if other user interaction triggers a refresh in the wiki, the state of the checkbox (and this the card) might not be preserved across the refresh cycle.
For the case I’m considering, this would probably be an upside. The backs of the cards should be hidden most of the time. I might even consider only showing them while you hover or press them.
Mostly, I’m simply going to be storing away this information. It was something to research while I was stuck on another problem. That one is now cleared up, and I’ll go back to what I was working on. But I will be using this in a few weeks.
Thank you for all your help, @arunnbabu81, @TW_Tones, and @saqimtiaz!