[jquery] Jquery UI tooltip does not support html content

Today, I upgraded all of my jQuery plugs-in with jQuery 1.9.1. And I started to use jQueryUI tooltip with jquery.ui.1.10.2. Everything was good. But when I used HTML tags in the content (in the title attribute of the element I was applying the tooltip to), I noticed that HTML is not supported.

This is screenshot of my tooltip:

enter image description here

How can I make HTML content work with jQueryUI tooltip in 1.10.2?

This question is related to jquery html jquery-ui jquery-ui-tooltip

The answer is


From http://bugs.jqueryui.com/ticket/9019

Putting HTML within the title attribute is not valid HTML and we are now escaping it to prevent XSS vulnerabilities (see #8861).

If you need HTML in your tooltips use the content option - http://api.jqueryui.com/tooltip/#option-content.

Try to use javascript to set html tooltips, see below

$( ".selector" ).tooltip({
   content: "Here is your HTML"
});

Replacing the \n or the escaped <br/> does the trick while keeping the rest of the HTML escaped:

$(document).tooltip({
    content: function() {
        var title = $(this).attr("title") || "";
        return $("<a>").text(title).html().replace(/&lt;br *\/?&gt;/, "<br/>");
    },
});

Html Markup

Tool-tip Control with class ".why", and Tool-tip Content Area with class ".customTolltip"

$(function () {
                $('.why').attr('title', function () {
                    return $(this).next('.customTolltip').remove().html();
                });
                $(document).tooltip();
            });

You may modify the source code 'jquery-ui.js' , find this default function for retrieving target element's title attribute content.

var tooltip = $.widget( "ui.tooltip", {
version: "1.11.4",
options: {
    content: function() {
        // support: IE<9, Opera in jQuery <1.7
        // .text() can't accept undefined, so coerce to a string
        var title = $( this ).attr( "title" ) || "";
        // Escape title, since we're going from an attribute to raw HTML
        return $( "<a>" ).text( title ).html();
    },

change it to

var tooltip = $.widget( "ui.tooltip", {
version: "1.11.4",
options: {
    content: function() {
        // support: IE<9, Opera in jQuery <1.7
        // .text() can't accept undefined, so coerce to a string
        if($(this).attr('ignoreHtml')==='false'){
            return $(this).prop("title");
        }
        var title = $( this ).attr( "title" ) || "";
        // Escape title, since we're going from an attribute to raw HTML
        return $( "<a>" ).text( title ).html();
    },

thus whenever you want to display html tips , just add an attribute ignoreHtml='false' on your target html element; like this <td title="<b>display content</b><br/>other" ignoreHtml='false'>display content</td>


To expand on @Andrew Whitaker's answer above, you can convert your tooltip to html entities within the title tag so as to avoid putting raw html directly in your attributes:

_x000D_
_x000D_
$('div').tooltip({_x000D_
    content: function () {_x000D_
        return $(this).prop('title');_x000D_
    }_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>_x000D_
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>_x000D_
<div class="tooltip" title="&lt;div&gt;check out these kool &lt;i&gt;italics&lt;/i&gt; and this &lt;span style=&quot;color:red&quot;&gt;red text&lt;/span&gt;&lt;/div&gt;">Hover Here</div>
_x000D_
_x000D_
_x000D_

More often than not, the tooltip is stored in a php variable anyway so you'd only need:

<div title="<?php echo htmlentities($tooltip); ?>">Hover Here</div>

You can also achieve this completely without jQueryUI by using CSS styles. See the snippet below:

_x000D_
_x000D_
div#Tooltip_Text_container {_x000D_
  max-width: 25em;_x000D_
  height: auto;_x000D_
  display: inline;_x000D_
  position: relative;_x000D_
}_x000D_
_x000D_
div#Tooltip_Text_container a {_x000D_
  text-decoration: none;_x000D_
  color: black;_x000D_
  cursor: default;_x000D_
  font-weight: normal;_x000D_
}_x000D_
_x000D_
div#Tooltip_Text_container a span.tooltips {_x000D_
  visibility: hidden;_x000D_
  opacity: 0;_x000D_
  transition: visibility 0s linear 0.2s, opacity 0.2s linear;_x000D_
  position: absolute;_x000D_
  left: 10px;_x000D_
  top: 18px;_x000D_
  width: 30em;_x000D_
  border: 1px solid #404040;_x000D_
  padding: 0.2em 0.5em;_x000D_
  cursor: default;_x000D_
  line-height: 140%;_x000D_
  font-size: 12px;_x000D_
  font-family: 'Segoe UI';_x000D_
  -moz-border-radius: 3px;_x000D_
  -webkit-border-radius: 3px;_x000D_
  border-radius: 3px;_x000D_
  -moz-box-shadow: 7px 7px 5px -5px #666;_x000D_
  -webkit-box-shadow: 7px 7px 5px -5px #666;_x000D_
  box-shadow: 7px 7px 5px -5px #666;_x000D_
  background: #E4E5F0  repeat-x;_x000D_
}_x000D_
_x000D_
div#Tooltip_Text_container:hover a span.tooltips {_x000D_
  visibility: visible;_x000D_
  opacity: 1;_x000D_
  transition-delay: 0.2s;_x000D_
}_x000D_
_x000D_
div#Tooltip_Text_container img {_x000D_
  left: -10px;_x000D_
}_x000D_
_x000D_
div#Tooltip_Text_container:hover a span.tooltips {_x000D_
  visibility: visible;_x000D_
  opacity: 1;_x000D_
  transition-delay: 0.2s;_x000D_
}
_x000D_
<div id="Tooltip_Text_container">_x000D_
  <span><b>Tooltip headline</b></span>_x000D_
  <a href="#">_x000D_
    <span class="tooltips">_x000D_
        <b>This is&nbsp;</b> a tooltip<br/>_x000D_
        <b>This is&nbsp;</b> another tooltip<br/>_x000D_
    </span>_x000D_
  </a>_x000D_
  <br/>Move the mousepointer to the tooltip headline above. _x000D_
</div>
_x000D_
_x000D_
_x000D_

The first span is for the displayed text, the second span for the hidden text, which is shown when you hover over it.


To avoid placing HTML tags in the title attribute, another solution is to use markdown. For instance, you could use [br] to represent a line break, then perform a simple replace in the content function.

In title attribute:

"Sample Line 1[br][br]Sample Line 2"

In your content function:

content: function () {
    return $(this).attr('title').replace(/\[br\]/g,"<br />");
}

I solved it with a custom data tag, because a title attribute is required anyway.

$("[data-tooltip]").each(function(i, e) {
    var tag = $(e);
    if (tag.is("[title]") === false) {
        tag.attr("title", "");
    }
});

$(document).tooltip({
    items: "[data-tooltip]",
    content: function () {
        return $(this).attr("data-tooltip");
    }
});

Like this it is html conform and the tooltips are only shown for wanted tags.


As long as we're using jQuery (> v1.8), we can parse the incoming string with $.parseHTML().

$('.tooltip').tooltip({
    content: function () {
        var tooltipContent = $('<div />').html( $.parseHTML( $(this).attr('title') ) );
        return tooltipContent;
    },
}); 

We'll parse the incoming string's attribute for unpleasant things, then convert it back to jQuery-readable HTML. The beauty of this is that by the time it hits the parser the strings are already concatenates, so it doesn't matter if someone is trying to split the script tag into separate strings. If you're stuck using jQuery's tooltips, this appears to be a solid solution.


None of the solutions above worked for me. This one works for me:

$(document).ready(function()
{
    $('body').tooltip({
        selector: '[data-toggle="tooltip"]',
        html: true
     });
});

$(function () {
         $.widget("ui.tooltip", $.ui.tooltip, {
             options: {
                 content: function () {
                     return $(this).prop('title');
                 }
             }
         });

         $('[rel=tooltip]').tooltip({
             position: {
                 my: "center bottom-20",
                 at: "center top",
                 using: function (position, feedback) {
                     $(this).css(position);
                     $("<div>")
                         .addClass("arrow")
                         .addClass(feedback.vertical)
                         .addClass(feedback.horizontal)
                         .appendTo(this);
                 }
             }
         });
     });

thanks for post and solution above.

I have updated the code little bit. Hope this might help you.

http://jsfiddle.net/pragneshkaria/Qv6L2/49/


add html = true to the tooltip options

$({selector}).tooltip({html: true});

Update
it's not relevant for jQuery ui tooltip property - it's true in bootstrap ui tooltip - my bad!


another solution will be to grab the text inside the title tag & then use .html() method of jQuery to construct the content of the tooltip.

$(function() {
  $(document).tooltip({
    position: {
      using: function(position, feedback) {
        $(this).css(position);
        var txt = $(this).text();
        $(this).html(txt);
        $("<div>")
          .addClass("arrow")
          .addClass(feedback.vertical)
          .addClass(feedback.horizontal)
          .appendTo(this);
      }
    }
  });
});

Example: http://jsfiddle.net/hamzeen/0qwxfgjo/


Instead of this:

$(document).tooltip({
    content: function () {
        return $(this).prop('title');
    }
});

use this for better performance

$(selector).tooltip({
    content: function () {
        return this.getAttribute("title");
    },
});

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to jquery-ui

How to auto adjust the div size for all mobile / tablet display formats? jQuery not working with IE 11 JavaScript Uncaught ReferenceError: jQuery is not defined; Uncaught ReferenceError: $ is not defined Best Practice to Organize Javascript Library & CSS Folder Structure Change table header color using bootstrap How to get HTML 5 input type="date" working in Firefox and/or IE 10 Form Submit jQuery does not work Disable future dates after today in Jquery Ui Datepicker How to Set Active Tab in jQuery Ui How to use source: function()... and AJAX in JQuery UI autocomplete

Examples related to jquery-ui-tooltip

Jquery UI tooltip does not support html content