Tooltip
The tooltip provides additional information to a context that is not visible by default and requires an action to be seen.
The tooltip provides additional information to a context that is not visible by default and requires an action to be seen. A tooltip extends the balloon component by adding functionality and semantic value, effectively connection the information to the source element. The tooltip is attached to a target and it's position is relative to it, then they can be and displayed as the user interacts with it.
Only use them when all other options are not possible since they are hard to implement in an accessible way.
If you really must implement a tooltip, make sure to include ARIA
and role
attributes accordingly.
Markup
- Tooltips must be attached to an interactive element (link or button) to make sure all users will be able to access them using mouse or keyboard alike;
- Both the target and the tooltip block must be wrapped into a
.flix-tooltip-target
element; - Every tooltip block must be defined as a separate HTML
.flix-tooltip
element which has arole="tooltip"
role. - To toggle the tooltip you must manage the active class modifier as well as the
aria
attributes.
Notice: Honeycomb provides a Tooltip.js plugin that manages all of the class toggling and accessibility attributes for you, so make sure to check it out!
Below is a simplified code example, it creates proper relative position context and allows you using different positioning options mentioned bellow:
<span class="flix-tooltip-target">
<button aria-label="Open Tooltip" class="flix-btn flix-btn--square flix-btn--primary" aria-controls="flix-tooltip" aria-describedby="flix-tooltip" aria-expanded="true">
<i class="flix-icon flix-icon-info-solid" aria-hidden="true"></i>
</button>
<div id="flix-tooltip" role="tooltip" class="flix-tooltip flix-tooltip--active">
<div class="flix-tooltip__content">
Some content
</div>
<button class="flix-tooltip__close flix-btn flix-btn--square flix-btn--sm flix-btn--link" aria-label="Close Tooltip"></button>
</div>
</span>
flix-tooltip__content
- Here goes the content of your tooltip and is a required element.
flix-tooltip__close
- This is optional and must have an `aria-label`. Add it when you need that closing button.
Modifiers
flix-tooltip--active
- Controls if the tooltip is visible or not, combine it with the
hidden
attribute to inform assistive technologies of the tooltip status. flix-tooltip--danger
flix-tooltip--error
(deprecated)- Enables the danger state for the tooltip with danger color background and white text.
flix-tooltip--content-fit
flix-tooltip--small
(deprecated)- Makes the tooltip width content aware and has smaller paddings.
Position and Alignment Modifiers
The tooltip position modifier controls which side of the target the tooltip will show up and the tooltip alignment controls the arrow position and the tooltip start point.
Following position modifiers are available:
flix-tooltip--left
- to position the tooltip to the left;
flix-tooltip--top
- to position the tooltip on top;
flix-tooltip--bottom
- to position the tooltip at the bottom;
And here are the possible alignments:
flix-tooltip--start
- to position at the start of the target;
flix-tooltip--end
- to position the end of the target;
If no modifier is provided the tooltip defaults is: position to the right and central alignment relative to the source element.
You can combine position and alignment modifiers, e.g. flix-tooltip--top
and flix-tooltip--start
CSS classes.
For tooltip targets that are inline elements you must add the flix-tooltip-target--inline
modifier to apply necessary alignment adjustments.
Tooltip Alignment: start
This is the default tooltip alignment
Tooltip Alignment: end
Tooltip Alignment: start
You don't need to add any modifiers here
Tooltip Alignment: end
Tooltip Alignment: start
This is the default tooltip alignment
Tooltip Alignment: end
Tooltip Alignment: start
This is the default tooltip alignment
Tooltip Alignment: end
<style>
#docs-style-tooltip-cross {
display: flex;
align-items: center;
justify-content: center;
}
</style>
<div class="docs-style-tooltip">
<div class="flix-grid">
<div class="flix-col-12 flix-has-text-centered">
<span class="flix-tooltip-target flix-space-2-right">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-botsta" data-tooltip="tooltip-botsta">
bottom-start
</button>
<div id="tooltip-botsta" role="tooltip" class="flix-tooltip flix-tooltip--bottom flix-tooltip--start js-flix-tooltip--bottom-start" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: bottom<br/>
Tooltip Alignment: start
</div>
</div>
</span>
<span class="flix-tooltip-target flix-space-2-right">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-bot" data-tooltip="tooltip-bot">
bottom
</button>
<div id="tooltip-bot" role="tooltip" class="flix-tooltip flix-tooltip--bottom js-flix-tooltip--bottom" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: bottom<br/>
This is the default tooltip alignment
</div>
</div>
</span>
<span class="flix-tooltip-target">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-botend" data-tooltip="tooltip-botend">
bottom-end
</button>
<div id="tooltip-botend" role="tooltip" class="flix-tooltip flix-tooltip--bottom flix-tooltip--end js-flix-tooltip--bottom-end" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: bottom<br/>
Tooltip Alignment: end
</div>
</div>
</span>
</div>
<div class="flix-col-4 flix-has-text-right">
<span class="flix-tooltip-target flix-tooltip-target--inline flix-space-1-bottom">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-rigsta" data-tooltip="tooltip-rigsta">
right-start
</button>
<div id="tooltip-rigsta" role="tooltip" class="flix-tooltip flix-tooltip--right flix-tooltip--start js-flix-tooltip--right-start" hidden="">
<div class="flix-tooltip__content">
This is the default tooltip position<br/>
Tooltip Alignment: start
</div>
</div>
</span>
<div class="flix-tooltip-target flix-space-1-bottom">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-default" data-tooltip="tooltip-default">
right
</button>
<div id="tooltip-default" role="tooltip" class="flix-tooltip js-flix-tooltip--right" hidden="">
<div class="flix-tooltip__content">
This is the default tooltip<br/>
You don't need to add any modifiers here
</div>
</div>
</div>
<span class="flix-tooltip-target flix-tooltip-target--inline">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-rigend" data-tooltip="tooltip-rigend">
right-end
</button>
<div id="tooltip-rigend" role="tooltip" class="flix-tooltip flix-tooltip--right flix-tooltip--end js-flix-tooltip--right-end" hidden="">
<div class="flix-tooltip__content">
This is the default tooltip position<br/>
Tooltip Alignment: end
</div>
</div>
</span>
</div>
<div id="docs-style-tooltip-cross" class="flix-col-4">
<i class="flix-icon flix-icon--size-8 flix-icon-plus" aria-hidden="true"></i>
</div>
<div class="flix-col-4 flix-has-text-left">
<div class="flix-tooltip-target flix-space-1-bottom">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-lefsta" data-tooltip="tooltip-lefsta">
left-start
</button>
<div id="tooltip-lefsta" role="tooltip" class="flix-tooltip flix-tooltip--left flix-tooltip--start js-flix-tooltip--left-start" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: left<br/>
Tooltip Alignment: start
</div>
</div>
</div>
<div class="flix-tooltip-target flix-space-1-bottom">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-left" data-tooltip="tooltip-left">
left
</button>
<div id="tooltip-left" role="tooltip" class="flix-tooltip flix-tooltip--left js-flix-tooltip--left" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: left<br/>
This is the default tooltip alignment
</div>
</div>
</div>
<div class="flix-tooltip-target">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-lefend" data-tooltip="tooltip-lefend">
left-end
</button>
<div id="tooltip-lefend" role="tooltip" class="flix-tooltip flix-tooltip--left flix-tooltip--end js-flix-tooltip--left-end" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: left<br/>
Tooltip Alignment: end
</div>
</div>
</div>
</div>
<div class="flix-col-12 flix-has-text-centered">
<span class="flix-tooltip-target flix-space-2-right">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-topsta" data-tooltip="tooltip-topsta">
top-start
</button>
<div id="tooltip-topsta" role="tooltip" class="flix-tooltip flix-tooltip--top flix-tooltip--start js-flix-tooltip--top-start" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: top<br/>
Tooltip Alignment: start
</div>
</div>
</span>
<span class="flix-tooltip-target flix-space-2-right">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-top" data-tooltip="tooltip-top">
top
</button>
<div id="tooltip-top" role="tooltip" class="flix-tooltip flix-tooltip--top js-flix-tooltip--top" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: top<br/>
This is the default tooltip alignment
</div>
</div>
</span>
<span class="flix-tooltip-target">
<button type="button" class="flix-btn flix-btn--link" aria-describedby="tooltip-topend" data-tooltip="tooltip-topend">
top-end
</button>
<div id="tooltip-topend" role="tooltip" class="flix-tooltip flix-tooltip--top flix-tooltip--end js-flix-tooltip--top-end" hidden="">
<div class="flix-tooltip__content">
Tooltip Position: top<br/>
Tooltip Alignment: end
</div>
</div>
</span>
</div>
</div>
</div>
Size Modifiers
The tooltip accepts 2 extra size modifiers, besides the regular size:
flix-tooltip--medium
- The medium tooltip is 372px wide.
flix-tooltip--large
- The large tooltip is 492px wide.
<div class="flix-space-4-bottom">
<span class="flix-tooltip-target">
<button aria-label="Open Regular Tooltip" class="flix-btn flix-btn--square flix-btn--primary" aria-controls="flix-tooltip-r" aria-describedby="flix-tooltip-r" aria-expanded="true">
<i class="flix-icon flix-icon-info-solid" aria-hidden="true"></i>
</button>
<div id="flix-tooltip-r" role="tooltip" class="flix-tooltip flix-tooltip--active">
<div class="flix-tooltip__content">
Regular tooltip for little text
</div>
</div>
</span>
</div>
<div class="flix-space-4-bottom">
<span class="flix-tooltip-target">
<button aria-label="Open Medium Tooltip" class="flix-btn flix-btn--square flix-btn--primary" aria-controls="flix-tooltip-m" aria-describedby="flix-tooltip-m" aria-expanded="true">
<i class="flix-icon flix-icon-info-solid" aria-hidden="true"></i>
</button>
<div id="flix-tooltip-m" role="tooltip" class="flix-tooltip flix-tooltip--medium flix-tooltip--active">
<div class="flix-tooltip__content">
Medium tooltip fits more content
</div>
</div>
</span>
</div>
<div class="flix-space-4-bottom">
<span class="flix-tooltip-target">
<button aria-label="Open Large Tooltip" class="flix-btn flix-btn--square flix-btn--primary" aria-controls="flix-tooltip-l" aria-describedby="flix-tooltip-l" aria-expanded="true">
<i class="flix-icon flix-icon-info-solid" aria-hidden="true"></i>
</button>
<div id="flix-tooltip-l" role="tooltip" class="flix-tooltip flix-tooltip--large flix-tooltip--active">
<div class="flix-tooltip__content">
Large tooltip holds a lot of text, can even add some columns.
</div>
</div>
</span>
</div>
Error tooltip applied to a form element
It is possible to attach a tooltip to a form element when you must provide more details about an aria-invalid
input make sure to connect your input with the error message by using the aria-errormessage
on your input and
an id
and aria-live
on your tooltip.
Finally you can add flix-tooltip--error
modifier to your tooltip to enable the error state.
Wrap the input and the tooltip with the flix-tooltip-target
container and add the necessary modifiers.
Notice: The tooltip does not override the content color, even on error state, so if you want to add custom HTML elements as tooltip content, pay attention to text color so the contrast is acceptable.
<div class="flix-form-row">
<div class="flix-form-row flix-form-row--small">
<div class="flix-input flix-input--error">
<label for="tooltip-input" class="flix-input__label flix-label">Type some data:</label>
<div class="flix-tooltip-target">
<input type="text" id="tooltip-input" class="flix-input__field" value="Wrong data!" aria-invalid="true" aria-errormessage="invalid-input-description-00"/>
<div role="tooltip" id="invalid-input-description-00" class="flix-tooltip flix-tooltip--active flix-tooltip--right flix-tooltip--error flix-tooltip--small" aria-live="assertive">
<div class="flix-tooltip__content">
Required
</div>
</div>
</div>
</div>
</div>
</div>
Using the plugin
The tooltip plugin is a very handy script that will handle all of the necessary attributes to show / hide tooltips and also wire it with the required accessibility features.
We strongly advise that you use the plugin since controlling tooltips requires you to keep many attributes in sync and the plugin makes things a lot easier!
- Include the plugin from our CDN at the end of your page:
<script src="https://honeycomb.flixbus.com/dist/{VERSION_TAG}/js/tooltip.js"></script>
- Initialize the plugin:
document.addEventListener("DOMContentLoaded", function() { tooltip.init(); });
- Add a unique
id
to each tooltip you want the plugin to control, you must add them to theflix-tooltip
element; - Finally, connect the target to the tooltip by passing the tooltip
id
as value to the target'sdata-tooltip
attribute; - If you wish to change the default event trigger to hover, just add
data-event="hover"
to the target;
Voila! The plugin will automatically add the correct role and setup all aria attributes according to the event you chose.
Making it work without the plugin
Before you continue we would really like to emphasize that you should use the plugin! There are lots of moving pieces that need to be kept in sync so tooltips work nicely and in an accessible way. But if you really must, here it goes:
You must:
- Only attach tooltips to discoverable elements, e.g.: a button or a link.
- Add
role="tooltip"
and an uniqueid
to the tooltip element; - If the tooltip starts hidden, add the
hidden
attribute to the tooltip element; - Add
aria-describedby="{the tooltip id}"
to the target, this allows screen readers to read the content of the tooltip when the target receives focus; - Only If the tooltip is controlled with click:
- Add
aria-controls="{the tooltip id}"
to the target; - Add
aria-expanded="{true|false}"
to the target and keep it in sync with the tooltip status;
- Add
Hover tooltips are announced automatically and don't need the controls / expanded feature.
Opening the tooltip:
- Remove the
hidden
attribute from the tooltip element to inform assistive technologies; - Add the
flix-tooltip--active
modifier to the tooltip element class to visually display the tooltip; - If tooltip is controlled with click: update the
aria-expanded
attribute from the target toaria-expanded="true"
;
Closing the tooltip:
- You must allow users to close the tooltip by:
- Clicking again the tooltip target or focusing away from it, depending on the event handler;
- Clicking anywhere outside of the tooltip;
- Pressing the
ESC
key;
- Add the
hidden
attribute to the tooltip element; - Remove the
--active
modifier; - If tooltip works on click: update
aria-expanded
from the target to"false"
;