How to add styled tooltips to Webflow without using jQuery

Learn how to add fully styled, animated tooltips to any Webflow element using Tippy.js, no jQuery needed.

How to add styled tooltips to Webflow without using jQuery

Colin Lateano
Developer Evangelist
View author profile
Colin Lateano
Developer Evangelist
View author profile
Table of contents

The title attribute gives you a tooltip, but not a good one. It appears after a delay that the browser controls and looks different on every OS and browser. Also, it can't be styled. Tippy.js solves all three without requiring jQuery.

The `title` attribute tooltip in Webflow renders after a browser-controlled delay, looks different in Safari vs. Chrome, and can't be styled. It's one of the most frequently raised tooltip issues, and the most-referenced fix (Tooltipster) requires jQuery, which you shouldn't be adding to new projects.

Tippy.js offers an alternative. It requires no jQuery, the CDN version is stable at v6.3.7, and it can be set up in Webflow in a few minutes. You get full control over placement, animation, and content, including rich HTML inside the tooltip.

In this guide, we explore the complete setup: loading the library, marking up elements, initializing with options, and fixing the four failure modes that catch most developers the first time.

What do you need to add tooltips in Webflow?

You need a paid Webflow plan that allows custom code. That’s the only hard requirement. No external accounts, API keys, or third-party services.

The Custom Code Embed element and the Site Settings custom code sections are available on any paid Site plan (Basic, CMS, Business, or Enterprise) and on Core, Growth, Agency, and Freelancer Workspace plans. Free plans cannot use custom code.

Once you have custom code access, the setup takes two locations in Webflow: Site Settings for loading the library, and Element Settings for marking up individual elements. Here's how each step works.

5 steps to add Tippy.js tooltips to Webflow

The setup consists of two distinct phases: loading Tippy.js globally via Site Settings and configuring it to activate specific elements. The full implementation requires no more than a few blocks of code. Here's what each one does and where it goes.

1. Load Tippy.js in Site Settings

You start by pasting two script tags into Webflow's Footer code section: one for Popper.js (now primarily maintained as Floating UI), the positioning engine Tippy.js requires and one for Tippy.js itself. Navigate to Site Settings → Custom code → Footer code to get there.

Tippy.js depends on Popper.js for positioning logic. You load both via CDN: Popper first, Tippy second.

Now, paste both script tags into the Footer code section (before </body>):

<!-- Popper.js (required by Tippy.js for positioning) -->
<script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>

<!-- Tippy.js v6 -->
<script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>

Here’s what that looks like:

The tippy-bundle version packages Popper.js and the Tippy.js CSS together.

If your project has a Content Security Policy that restricts inline styles, load them separately instead:

<link rel="stylesheet" href="https://unpkg.com/tippy.js@6/dist/tippy.css" />

Put that CSS link in the Head code section if you're using the separate stylesheet. The script tags still go in the Footer code.

Why footer? Scripts in the head run before the DOM exists, so Tippy.js tries to find elements before your page renders. Putting scripts in the footer ensures the DOM is fully loaded when Tippy.js initializes.

After saving, both libraries load on every published page of your site. They will not execute in the Webflow Designer canvas. Tippy.js only runs on published pages.

2. Add the data-tippy-content attribute to each element

Add a custom attribute named data-tippy-content to each element that should have a tooltip. The value becomes the tooltip text.

Select the target element in the Webflow Designer, open Element Settings (press D, or click the gear icon in the top toolbar), and scroll to the Custom Attributes section.

Then, add the attribute name and its value:

  • Attribute name: data-tippy-content
  • Value: [the text you want to appear in the tooltip, e.g., "Opens in a new tab" or "Required field"]

The value you enter here is the tooltip text. Each element gets its own value, and that's exactly what appears in the bubble when someone hovers over it.

Tippy.js reads data-tippy-content on initialization and uses it as the tooltip content. No class name needed. No title attribute required. Repeat this for every element you want a tooltip on. You can use different content values per element. Each one gets its own independent tooltip instance.

One note on interactive elements: if you're adding this to a non-interactive HTML element (a

, a <span>, a Webflow Text element), also set Cursor to Pointer in the Style panel. Without it, iOS Safari won't recognize the tap, and the tooltip won't fire on touch devices.

The element is now marked. The tooltip won't appear yet. That requires the initialization call in Step 3.

3. Initialize Tippy.js in the footer custom code

Add the initialization call after your Tippy.js script tags.

In Site Settings → Custom code → Footer code, after the two script tags from Step 1, add:

<script>
  tippy('[data-tippy-content]');
</script>

This single call selects every element on the page with a data-tippy-content attribute and activates a Tippy.js instance on each one. Tippy.js automatically reads the attribute value as the tooltip content.

Customizing behavior

To customize behavior (position, animation, delay), pass an options object:

<script>
  tippy('[data-tippy-content]', {
    placement: 'bottom',   // 'top', 'bottom', 'left', 'right', or auto variants
    animation: 'scale',    // 'fade' (default), 'scale', 'shift-away', 'shift-toward', 'perspective'
    delay: [100, 200],     // [show delay in ms, hide delay in ms]
    arrow: true            // show the arrow pointer (default: true)
  });
</script>

Options apply globally to every tooltip on the page.

If you use any animation other than 'fade', load the corresponding CSS in Site Settings → Custom code → Head code:

<!-- Required for 'scale' animation -->
<link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css" />

Replace scale with shift-away, shift-toward, or perspective, depending on which animation you're using. Without this CSS, the animation setting is silently ignored, and the default \fade animation is used instead.

Using different settings per element

If you need different settings per element, say placement: 'right' on one element and placement: 'top' on another, initialize each set separately with a more specific selector, or use Tippy.js's data-tippy-* props to override per element:

<script>
  // Global defaults
  tippy('[data-tippy-content]', {
    placement: 'top',
    animation: 'fade'
  });
</script>

data-tippy-placement="right"  ← set this as a custom attribute on specific elements to override

The full list of available options is in the Tippy.js props reference.

Save, and your site is ready to publish. Tippy.js will activate on every element with data-tippy-content on page load.

4. Publish and test on the live site

Click Publish in the top right of the Designer. Select your domain and publish.

Once publishing finishes, open your live site URL. Custom code does not execute in the Webflow Designer canvas. In preview mode, custom code is turned off by default. You can enable it by clicking the "Enable custom code" toggle in the bottom left of the preview window.

Hover over any element you added data-tippy-content to in Step 2.

You should see:

  • A tooltip bubble appears above the element (or at your configured placement)
  • A fade animation plays (or your configured animation)
  • The tooltip disappears when you move the cursor away

On mobile, the tooltip triggers on tap. The element must have cursor: pointer in its CSS for this to work on iOS Safari. If tapping does nothing, the troubleshooting section below covers the fix.

5. Render HTML content inside tooltips (optional)

By default, Tippy.js treats the data-tippy-content value as plain text.

To render HTML inside a tooltip (formatted content, icons, links), enable allowHTML:

<script>
  tippy('[data-tippy-content]', {
    allowHTML: true
  });
</script>

Then set the custom attribute value to an HTML string:

data-tippy-content  →  <strong>Required field</strong> — must be a valid email address

A few things to keep in mind here. allowHTML: true only matters if the browser needs to parse markup in the content string. For most tooltip use cases (plain labels, short descriptions), you don't need it. If you're using it, make sure the content is safe. Don't pass unsanitized user-generated strings directly into allowHTML: true tooltips.

For complex tooltip content beyond a short string (a card with an image, a formatted definition), you can reference an off-screen DOM element instead of an inline string.

What causes Tippy.js tooltips to fail in Webflow?

Most failures fall into four buckets: testing in the wrong environment, an attribute typo, the iOS tap issue, or a CSS containment conflict.

Here's how to identify and fix each.

Tooltips don't appear anywhere on the page

You've published the site and hovered over elements, but nothing happens.

Check 1: Are you testing on the live site? Custom code does not execute in the Webflow Designer canvas. If you're viewing the canvas or a share preview URL, Tippy.js isn't executing. Open your published domain or .webflow.io subdomain.

Check 2: Is the initialization script loading after the library? The tippy(...) call must run after both the Popper.js and Tippy.js script tags. All three blocks should be in the Footer code section, in this order: Popper first, Tippy second, your init script third. If the init script is in the Head code section, Tippy.js doesn't exist yet when it fires.

Check 3: Open the browser console. Right-click on the published page → Inspect → Console. If you see tippy is not defined or a 404 on the CDN URLs, one of the scripts didn't load. Check Site Settings → Custom code to confirm that the script tags are in the Footer code and that the URLs are correct.

Some elements get tooltips, others don't

Most elements respond, but a handful do nothing, even though they have data-tippy-content set.

Cause: The attribute name has a typo. Tippy.js selects elements using '[data-tippy-content]' exactly. One character off, and the element is invisible to the selector.

In the Webflow Designer, open Element Settings on the affected element and verify the custom attribute name is data-tippy-content, all lowercase, with hyphens, not underscores.

One thing that catches people: if the value is empty (data-tippy-content with no value set), Tippy.js still initializes on the element but shows a blank tooltip. Make sure every element has a non-empty value.

Tooltips don't trigger on iOS when tapping the element

Hover tooltips work on desktop. Tapping the same element on iPhone or iPad in Safari does nothing.

Cause: iOS Safari does not fire touch or click events on elements that aren't natively interactive (links, buttons, inputs) unless the element has cursor: pointer set in CSS. This is a long-standing Safari behavior, not a Tippy.js limitation.

Since Tippy.js uses the focus event for touch, and focus doesn't fire on non-interactive elements without this CSS property, the tooltip never activates.

Fix: Select the trigger element in the Webflow Designer. In the Style panel, find the Cursor property under Miscellaneous (or search "cursor" in the search bar) and set it to Pointer. Publish and test on iOS.

This is the single most-reported mobile issue for custom JavaScript interactions on non-interactive elements in Webflow. The cursor change is a one-click fix.

Tooltip appears but is clipped or hidden behind another element

The tooltip triggers, but part of it is cut off by a container or hidden behind a sticky header.

Cause 1: overflow: hidden on a parent container. Tippy.js appends tooltips to document.body by default, which should prevent most clipping. If clipping still occurs, a parent with overflow: hidden or overflow: clip is the likely cause. Check parent elements in the Style panel.

Cause 2: z-index conflict. Tippy.js defaults to z-index: 9999. If a fixed header or modal overlay has a higher z-index, the tooltip renders behind it. Override Tippy.js's z-index in the options:

<script>
  tippy('[data-tippy-content]', {
    zIndex: 100000
  });
</script>

Set this higher than whatever is covering the tooltip.

Frequently asked questions

Do Tippy.js tooltips work inside Webflow CMS collection lists?

Yes. Add data-tippy-content as a custom attribute inside the collection list template. Tippy.js initializes on page load and picks up all matching elements in the rendered DOM, including CMS-generated ones. For dynamic tooltip content per item, bind a CMS field to the attribute value using Webflow's custom attribute binding.

Does Tippy.js conflict with Webflow's native Interactions?

No. Tippy.js runs independently from Webflow's Interactions system, including Interactions with GSAP. Both can target the same element without conflict. If a hover animation and a tooltip compete visually on the same element, add a short delay to the Tippy.js init options to offset the timing.

Do tooltips work on Webflow form inputs and labels?

Yes. Inputs, labels, selects, and textareas all support the data-tippy-content attribute. For form fields, use placement: 'right' so the tooltip doesn't sit above the label, and trigger: 'focus' so it only appears when the user focuses the field, not on hover.

Do tooltips work on the Webflow staging subdomain?

Yes. The .webflow.io staging subdomain runs the same published HTML as your custom domain. Tippy.js functions identically. The Designer canvas does not run custom code. Preview mode doesn't run it by default either, but you can enable it via the "Enable custom code" toggle in the lower-left corner of the preview window.


Last Updated
May 8, 2026
Category

Related articles

How to open a Typeform modal on button click in Webflow without redirecting users
How to open a Typeform modal on button click in Webflow without redirecting users

How to open a Typeform modal on button click in Webflow without redirecting users

How to open a Typeform modal on button click in Webflow without redirecting users

Development
By
Colin Lateano
,
,
Read article
The complete guide to syncing Webflow orders to Airtable with Zapier
The complete guide to syncing Webflow orders to Airtable with Zapier

The complete guide to syncing Webflow orders to Airtable with Zapier

The complete guide to syncing Webflow orders to Airtable with Zapier

Development
By
Colin Lateano
,
,
Read article
How to use the Webflow CMS API to read, write, and publish content programmatically
How to use the Webflow CMS API to read, write, and publish content programmatically

How to use the Webflow CMS API to read, write, and publish content programmatically

How to use the Webflow CMS API to read, write, and publish content programmatically

Development
By
Colin Lateano
,
,
Read article
How to send Webflow form submissions to HubSpot via Zapier without losing data
How to send Webflow form submissions to HubSpot via Zapier without losing data

How to send Webflow form submissions to HubSpot via Zapier without losing data

How to send Webflow form submissions to HubSpot via Zapier without losing data

Development
By
Colin Lateano
,
,
Read article

verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logosoundcloud logoreddit logothe new york times logoideo logoupwork logodiscord logo
verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logosoundcloud logoreddit logothe new york times logoideo logoupwork logodiscord logo

Get started for free

Try Webflow for as long as you like with our free Starter plan. Purchase a paid Site plan to publish, host, and unlock additional features.

Get started — it’s free
Watch demo

Try Webflow for as long as you like with our free Starter plan. Purchase a paid Site plan to publish, host, and unlock additional features.