Styling tooltips
Last updated
Last updated
Tooltips are pretty cool. Not only do they give you a preview of an entity before you decide to check it out, but in some cases they provide all the info you need without having to leave the current page (especially on Premium campaigns, where you can have them show a lot more than the basic 500-character excerpt from the entry). On the other hand, they can be a bit boring showing every preview in the same basic format.
When I created my DnD5 Condition Tooltips content pack and theme, one of my main goals was that you could hover a condition mention and see everything you need to know about it without moving from what you were reading. The second goal was to make it look like it came straight from the official rulebook, regardless of your campaign’s theming, and this guide will help you use the same tricks I did to customize tooltips to your own campaign or content pack.
Since Kanka’s tooltips are created via JavaScript when you hover a link and disappear from the page source when you move your pointer away, they can be very difficult to inspect and style in real time. To save you the trouble, you can copy the one below (current as of Kanka 2.0, November 2023) and paste it somewhere in your page inspector panel to see how your CSS changes affect it in real time. I will detail each component below.
The outermost layers (div[data-tippy-root]
and div.tippy-box
) mainly control the positioning and size of tooltips. You might want to do things like change the max-width
on [data-tippy-root]
and .tippy-box
, or adjust the transition-duration
on .tippy-box
.
The next layer, div.tippy-content
, also has a transition, as well as padding and font styles you may want to change:
Things get more interesting with div.tooltip-content
, as it has classes matching the tags on the target entity. That means you can style this part of the tooltip differently based on tags to use different colors, backgrounds, etc. to reflect an entity’s type or faction, for instance.
As you can see, tags are identified both by ID and slug, similar to what is found on mentions as described in Introduction to campaign CSS - Mention attributes. It’s unfortunate that these classes aren’t on the outermost layer, but I will come back to this below with a workaround I used for DnD5 Condition Tooltips.
Coming back to .tooltip-content
itself, it sets the padding and gap between the three blocks of content showing the entity’s info and excerpt as a flexbox:
Its first child doesn’t have a very recognizable class but is a single-row flexbox for the entity’s image (if enabled in your campaign’s Interface settings), name and title (for characters). The entity’s image is set inline as a background-image
on .cover-background
, and it is subject to the following rules, which you can override to alter the sizing, position, etc.:
.entity-names
, .entity-name
and .entity-subtitle
don’t have anything too special on them other than display: block
and font-related rules, and you can target them to change the font styling, center the text, etc.
.tooltip-content
’s second child is .tooltip-tags
, which simply shows the entity’s tags in a row. You may want to hide them entirely or change the size or margins of each .badge
.
The third child and final layer is .tooltip-text
, which contains the actual excerpt from the entity and is the class you would target for font styling that differs from the rest of the tooltip, or perhaps add an inner border or background. Note that depending on your campaign’s CSS, you may need to target paragraphs specifically with .tooltip-text p { ... }
to override global rules, and likewise for other elements.
Here is a small part of DnD5 Condition Tooltips to wrap up with a practical example of targeting and changing a few of those elements:
As we saw earlier, there are three layers of divs that we can’t target with tag-specific rules. For some styles like borders, backgrounds, padding or even tag-specific max widths, this is a problem. Thankfully, it’s solvable thanks to a fairly recent CSS pseudo-class: :has()
. In short, it allows us to look at whether an element contains some other element, something that had long been missing from CSS (a selector could only really look at what was above or before it in the document tree, not after or below).
Since :has()
is still recent, it is not fully supported on all browsers, especially on mobile. You can check for current compatibility stats and use fallbacks as explained below until it reaches sufficient adoption.
Unlike Kanka’s earlier tooltips, Tippy tooltips are nowhere near their associated link in the document object tree, which means we can’t target them based on their proximity to each other. Instead, we’ll have to rely on a subtle attribute of mentions called aria-expanded
. By default, this attribute is set to false
, but it switches to true
when hovered:
Since only one tooltip can be active at a time, and since the mention’s classes also indicate the target’s tags, as seen above, we can deduce the active tooltip’s tags even at the outermost level by checking if body
contains a mention with the necessary tag(s) and aria-expanded="true"
:
Now, the problem with this is you may end up breaking things for people on browsers that don’t support :has()
. In my DnD5 Conditions theme, I set a custom background image on the outer layers and text color on the inner content. Without :has()
, a user will likely have trouble reading the text because the custom color and default background aren’t suited to each other. This can be solved with a feature query checking whether the browser supports it.
Below, I check if body:has(a.entity-mention)
is considered valid by the browser. I don’t really need the full selector, as I’m only really concerned about :has()
, so I shortened it to something I can recognize easily.
With the not
keyword, I add a rule specifically for browsers that don’t support it; in this case, setting a slightly different background on .tooltip-content
instead — the first layer where I can see the target entity’s tags. It doesn’t look as good as a full-sized one, but it comes close to the overall look I’m aiming for and maintains legibility for everyone.
And that’s about it! If this guide helped you, please consider supporting my work with a tip on my Ko-fi page =) I am also sometimes available for commissions to help directly with your plugins or CSS.