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 a role="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--md 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
Enables the danger state for the tooltip with danger color background and white text.
flix-tooltip--content-fit
Makes the tooltip width content aware, has smaller paddings and does not break lines.

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.

<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&#x27;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

Tooltips will stretch to fit any content in them, but you can set a minimum size. The tooltip accepts 3 extra size modifiers, besides the regular size:

Default (no modifier)
The default tooltip is 252px wide.
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--danger 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 flix-form-row--small">
  <div class="flix-input flix-input--error">
    <label class="flix-label flix-input__label" for="example-error">
      Type some data:
    </label>
    <div class="flix-tooltip-target">
      <div class="flix-input__container">
        <input type="text" id="example-error" class="flix-input__field" aria-invalid="true" aria-errormessage="invalid-input-description-00" value="Invalid input"/>
        <span class="flix-input__feedback-icon" aria-hidden="true"></span>
      </div>
      <div role="tooltip" id="invalid-input-description-00" class="flix-tooltip flix-tooltip--active flix-tooltip--right flix-tooltip--danger flix-tooltip--content-fit" aria-live="assertive">
        <div class="flix-tooltip__content">
          Required
        </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 the flix-tooltip element;
  • Finally, connect the target to the tooltip by passing the tooltip id as value to the target's data-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 unique id 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;
  • 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;

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;
  • Update the aria-expanded attribute from the target to aria-expanded="true";

Closing the tooltip:

  • You must allow users to close the tooltip by:
    • Clicking again the tooltip target;
    • Clicking anywhere outside of the tooltip;
    • Pressing the ESC key;
  • Add the hidden attribute to the tooltip element;
  • Remove the --active modifier;
  • Update aria-expanded from the target to "false";