Reputation: 149
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 different like the background color. i.e I want multiple looks for tooltips. but I don't see how I can set custom tooltip styles for 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.
Upvotes: 2
Views: 16225
Reputation: 1
I too have been searching (far and wide) for an answer to apply different styles to selective tooltips in Bootsrap 4 and to say I was getting frustrated is an understatement.
Lots of threads simply address styling global .tooltip-inner or using scripting to accomplish this, even Bootstrap probably should have provided a simpler way.
Anyhow here's my own personal scenario & workaround.
I generally stick to the basic Bootstrap tooltip options (I assume this is working already, otherwise see update below) for various tooltips appearing on pages, but on my Navbar I have a keyboard shortcut Favicon in an anchor tag which I wanted to style. The way I accomplished this is by wrapping it in a span tag (or "data-container" as George put it [see credits]).
<link href='https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css' rel='stylesheet'/>
<link href='https://use.fontawesome.com/releases/v5.6.3/css/all.css' rel='stylesheet'/>
<script src='https://code.jquery.com/jquery-3.3.1.slim.min.js'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js'/>
<script src='https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js'/>
<nav>
...
<span class="tt_kb">
<a class="nav-item nav-link px-2" href="#" data-toggle="tooltip" placement="auto" data-html="true" container="body" trigger="hover" data-container=".tt_kb" data-boundary="window" title="Keyboard Shortcuts ... blah blah blah"><i class="far fa-keyboard"></i></a>
</span>
...
</nav>
<style>
.tt_kb .tooltip .tooltip-inner {
background-color: #3266FF;
text-align: left;
width: 200px;
position: relative;
right: 50px;
}
</style>
The odd thing for me is that for some reason the [position="auto"] didn't work (well) as I have the tt_kb Favicon on the top right hand side of the Navbar, half of the tooltip was disappearing outside my window, hence I added [position:relative & right:50px] in the CSS to get around this. Overall this worked reasonably well for me and I suppose with a little tweaking you could get this to work in your scenario.
Hope this help )
UPDATE
For those who don't have the general Bootstrap/Popper tooltips working you may want to add the following script & general styles to your code.
<script>
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
$('[data-toggle="tooltip"]').each(function(){
var options = {
html: true
};
if ($(this)[0].hasAttribute('data-type')) {
options['template'] =
'<div class="tooltip ' + $(this).attr('data-type') + '" role="tooltip">' +
' <div class="tooltip-arrow"></div>' +
' <div class="tooltip-inner"></div>' +
'</div>';
}
$(this).tooltip(options);
});
</script>
</style>
.tooltip.primary .tooltip-inner { background-color: #31b0d5; }
.tooltip.primary.top > .tooltip-arrow { border-top-color: #337ab7; }
.tooltip.primary.right > .tooltip-arrow { border-right-color: #337ab7; }
.tooltip.primary.bottom > .tooltip-arrow { border-bottom-color: #337ab7; }
.tooltip.primary.left > .tooltip-arrow { border-left-color: #337ab7; }
.tooltip.info .tooltip-inner { background-color: #31b0d5; }
.tooltip.info.top > .tooltip-arrow { border-top-color: #31b0d5; }
.tooltip.info.right > .tooltip-arrow { border-right-color: #31b0d5; }
.tooltip.info.bottom > .tooltip-arrow { border-bottom-color: #31b0d5; }
.tooltip.info.left > .tooltip-arrow { border-left-color: #31b0d5; }
.tooltip.success .tooltip-inner { background-color: #449d44; }
.tooltip.success.top > .tooltip-arrow { border-top-color: #449d44; }
.tooltip.success.right > .tooltip-arrow { border-right-color: #449d44; }
.tooltip.success.bottom > .tooltip-arrow { border-bottom-color: #449d44; }
.tooltip.success.left > .tooltip-arrow { border-left-color: #449d44; }
.tooltip.warning .tooltip-inner { background-color: #ec971f; }
.tooltip.warning.top > .tooltip-arrow { border-top-color: #ec971f; }
.tooltip.warning.right > .tooltip-arrow { border-right-color: #ec971f; }
.tooltip.warning.bottom > .tooltip-arrow { border-bottom-color: #ec971f; }
.tooltip.warning.left > .tooltip-arrow { border-left-color: #ec971f; }
.tooltip.danger .tooltip-inner { background-color: #d9534f; }
.tooltip.danger.top > .tooltip-arrow { border-top-color: #d9534f; }
.tooltip.danger.right > .tooltip-arrow { border-right-color: #d9534f; }
.tooltip.danger.bottom > .tooltip-arrow { border-bottom-color: #d9534f; }
.tooltip.danger.left > .tooltip-arrow { border-left-color: #d9534f; }
</style>
UPDATE
Added fully working JSFiddle Demo
NB For some reason the Navbar won't align right in the demo unless you view it zoomed at 110% or 125%!
Upvotes: 0
Reputation: 1429
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
Upvotes: 2
Reputation: 11342
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>
Upvotes: 4
Reputation: 65
try this
<i id="my-tooltip-1" class="fa fa-fire fa-lg" data-toggle="tooltip" data-placement="bottom" title="Fire Place"></i>
<style>
#my-tooltip-1 + .tooltip > .tooltip-inner {
padding: 15px;
font-size: 120%;
background-color: #FFEB6C;
color: #374D40;
/* do something */
}
#my-tooltip-1 + .tooltip > .tooltip-arrow {
background-color: #FFEB6C;
/* do something */
}
</style>
Upvotes: 0