Bootstrap Tooltips with different styles

12,848

Solution 1

Simple, I created a class to hold those CSS style called custom-tooltip:

/* Tooltip */

.custom-tooltip+.tooltip>.tooltip-inner {
  padding: 15px;
  font-size: 1.2em;
  background-color: #FFEB6C;
  color: #374D40;
}


/* Tooltip on bottom */

.custom-tooltip+.tooltip.bottom>.tooltip-arrow {
  border-bottom: 5px solid #FFEB6C;
}

$('i[data-toggle="tooltip"]').tooltip({
  animated: 'fade',
  placement: 'bottom'
});
/* Tooltip */

.custom-tooltip+.tooltip>.tooltip-inner {
  padding: 15px;
  font-size: 1.2em;
  background-color: #FFEB6C;
  color: #374D40;
}


/* Tooltip on top */
.custom-tooltip+.tooltip.top>.tooltip-arrow {
  border-top: 5px solid #FFEB6C;
}


/* Tooltip on bottom */
.custom-tooltip+.tooltip.bottom>.tooltip-arrow {
  border-bottom: 5px solid #FFEB6C;
}


/* Tooltip on left */
.custom-tooltip+.tooltip.left>.tooltip-arrow {
  border-left: 5px solid #FFEB6C;
}


/* Tooltip on right */
.custom-tooltip+.tooltip.right>.tooltip-arrow {
  border-right: 5px solid #FFEB6C;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />



<i class="fa fa-fire fa-lg custom-tooltip" data-toggle="tooltip" data-placement="bottom" title="Fire Place"></i>

Solution 2

I have prepared a quite universal solution for the bootstrap 3 tooltips' styling working with the dynamically created elements. It will work also in a case when a tooltip is generated not as a sibling to its element, but on a higher level of DOM, for example when a custom container option has been used:

<body>
    <div>
    <button type="button" class="btn btn-default" data-container="body" title="Tooltip text">Hover over me</button>
    </div>
</body>

The tooltip's <div> will be generated there as a sibling to <div>, instead of <button>...

Solution

Let's make the template option of the Bootstrap tooltip object dynamic:

$.fn.tooltip.Constructor.prototype.tip = function () {
    var template;
    var $e = this.$element;
    var o  = this.options;
    if (!this.$tip) {
        template = typeof o.template == 'function' ? o.template.call($e[0]) :  o.template;
        this.$tip = $(template);
        if (this.$tip.length != 1) {
            throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!');
        }
    }
    return this.$tip;
}

Prepare the tooltip template function. It will get all "tooltip-*" classes from the element with tooltip and append to the "tooltip-arrow" and "tooltip-inner" divs

tooltipTemplate = function () {
    var classList = ($(this).attr('class')||"").split(/\s+/);
    var filterTooltipPrefix = function(val){
        return val.startsWith('tooltip-');
    };
    var tooltipClasses = classList.filter(filterTooltipPrefix).join(' ');
    return '<div class="tooltip" role="tooltip"><div class="tooltip-arrow ' + tooltipClasses +'"></div><div class="tooltip-inner ' + tooltipClasses +'"></div></div>';
}

Ensure our function works in older browsers:

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function(searchString, position){
        position = position || 0;
        return this.substr(position, searchString.length) === searchString;
    };
}

Now enable the tooltips:

$('body').tooltip({ 
    selector: "[title]", 
    html: true,
    template: tooltipTemplate
});

Example:

HTML

<h1>Test tooltip styling</h1>
<div><span title="Long-long-long tooltip doesn't fit the single line">Hover over me 1</span></div>
<div><span class="tooltip-left" data-container="body" title="Example (left aligned):<br>Tooltip doesn't fit the single line, and is not a sibling">Hover over me 2</span></div>
<div><span class="tooltip-large tooltip-left" title="Example (left aligned):<br>This long text we want to have in the single line">Hover over me 3</span></div>

CSS

.tooltip-inner.tooltip-large {
    max-width: 300px;
}

.tooltip-inner.tooltip-left {
    text-align: left;
}

Here is working demo: https://www.bootply.com/Mz48qBWXFu

Note I was not able to run this code on jsfiddle, which uses Bootstrap 4. It throws an error: TOOLTIP: Option "template" provided type "function" but expected type "string"
Apparently some additional tweaking is necessary there.


UPDATE

Everything above was an overkill in 2 places:

Instead of posting the tooltip styling classes in the class property of an element, it is better to use a data- property. That would simplify the tooltipTemplate function and remove the startsWith code shim:

tooltipTemplate = function () {
    var tooltipClasses = $(this).data('tooltip-custom-classes');
    return '<div class="tooltip" role="tooltip"><div class="tooltip-arrow ' + tooltipClasses +'"></div><div class="tooltip-inner ' + tooltipClasses +'"></div></div>';
}

Much more important, we don't need to modify tooltip template at all. We should have a callback to the inserted.bs.tooltip event. That would simplify everything (thanks go to Oleg for his answer https://stackoverflow.com/a/42994192/9921853):

Bootstrap 3:

$(document).on('inserted.bs.tooltip', function(e) {
    var tooltip = $(e.target).data('bs.tooltip');
    tooltip.$tip.addClass($(e.target).data('tooltip-custom-class'));
});

Bootstrap 4:

$(document).on('inserted.bs.tooltip', function(e) {
    var tooltip = $(e.target).data('bs.tooltip');
    $(tooltip.tip).addClass($(e.target).data('tooltip-custom-class'));
});

Here are the whole examples:
for Bootstrap 3
for Bootstrap 4

Share:
12,848
PeeBee
Author by

PeeBee

Updated on August 02, 2022

Comments

  • PeeBee
    PeeBee over 1 year

    I have tooltips showing using data-toggle like in,

     <i class="fa fa-fire fa-lg" data-toggle="tooltip" data-placement="bottom" title="Fire Place"></i>
    

    I have styled the tooltips here using,

    .tooltip > .tooltip-inner {
    
    padding: 15px;
    font-size: 120%;
    background-color: #FFEB6C;
    color: #374D40;}
    

    I'd like tooltips on different places to look differentlylike the background color. i.e I want multiple looks for tooltips. but I don't see how I can set custom tooltip styles to each tooltip. I can't set a css class to each tooltip either since there's no such element,I'm setting tooltips through data-toggle.

    Is there any way I can make this work? Thanks.