Generating tooltips
Sometimes, the inner workings and expectations of a character sheet aren’t entirely obvious, but you don’t want to clutter it by adding explanatory text everywhere. Being on the Web gives us an easy way to have our cake and eat it too: tooltips. Kanka uses the Tippy library to generate its tooltips on entity mentions and various other elements, and we can tap into that library by simply adding a few data attributes to our HTML elements.
<button data-tooltip data-html="true" data-title="Hi, I’m Troy McClure. You might remember me from RPG classics such as <i>The Temple of Emmental Evil</i> and <i>Expedition to Plundermountain</i>.">This button wants to say something</button>

data-tooltip: Identifies the element as a tooltip holder at page load. There is no need to give it a value.
data-html: Optional parameter; if present and set to "true", HTML tags in the tooltip content will be parsed. Otherwise they will be treated as plain text.
data-title: The content that will be shown inside the tooltip when hovered. Can include HTML if
data-html
is set to "true".data-direction: By default, Kanka displays tooltips under the host element. You can set a different placement with this attribute. See https://atomiks.github.io/tippyjs/#placements for all supported values.
You can also replicate the hint icon in places such as the Pins sidebar of entities to better integrate your character sheet with Kanka:
<a href="#_" data-tooltip data-title="Do not include your shield’s bonus, as it will be added automatically." aria-label="Do not include your shield’s bonus, as it will be added automatically.">
<i class="fa-solid fa-question-circle" aria-hidden="true"></i>
</a>

Another possible format is to replace data-tooltip
with data-dropdown
. For example, you could borrow the styling of the post actions dropdown and trigger different JavaScript actions/functions based on which link the user clicks:
<div class="dropdown">
<a role="button" class="btn2 btn-ghost btn-sm" data-dropdown aria-expanded="false" data-tree="escape">
<i class="fa-solid fa-ellipsis-v " aria-hidden="true"></i>
<span class="sr-only">Actions</span>
</a>
<div class="dropdown-menu hidden" role="menu">
<a href="#_" class=" p-1 hover:bg-base-200 rounded flex items-center gap-2 text-sm text-base-content" onclick="alert('Hi!')">
Say hi
</a>
<a href="#_" class=" p-1 hover:bg-base-200 rounded flex items-center gap-2 text-sm text-base-content" onclick="alert('Hello!')">
Say hello
</a>
</div>
</div>

The logic here is that Tippy looks for an element that has data-dropdown
on it, then looks for the first element with the class dropdown-menu
on the same level (i.e. under the same parent element) to display on hover. Even if your tooltip’s content is not functionally a group of options, you can choose this approach when your tooltip has a complex HTML structure or a lot of text and you want it to be more legible than cramming it all in a data attribute.
Dynamic tooltip contents
If you use JavaScript to populate your character sheet, or more specifically to set or change a tooltip’s content after initial page load, you should note that Tippy will load before your script and only see the HTML elements and attributes that exist before your script runs; therefore, the tooltips’ contents may not match your intent. To circumvent this problem, I first insert the necessary elements in the HTML field of my plugin so that Tippy can recognize and handle them, e.g. <span data-tooltip>{{$_entity_name}}</span>
.
Then, in my JavaScript field, I can process and alter the intended tooltip content as needed, before invoking the _tippy.setContent()
method on each element.
For example, in one of my character sheets, I loop through every HTML element that has the data-tooltip
attribute but doesn’t already have a data-title
(e
) and tell Tippy to use the inner HTML of the element (which I have modified with JS) as its tooltip content:
document.querySelectorAll("[data-tooltip]:not([data-title])").forEach( (e) => {
if (e.innerHTML.length > 0) {
e.dataset.html = "true";
e._tippy.setContent(e.innerHTML);
}
Using this method, there is no need to set the data-title
attribute at all (and creating it alone would not update the Tippy instance, as it only looks at data-title
when initialized and does not watch for changes).
Last updated
Was this helpful?