Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bootstrap tooltip\popover - solving inconsistent placement to the left

I've been working on a project and I've noticed some inconsistency in bootstrap's behavior that I would like to solve.

When a popover (or tooltip, whatever, they're basically the same) is nearing the edge of the screen - if it's a right-sided one, when nearing the edge - it will contract so as not to go offscreen (it only works up to a point, but that's usually enough).

This doesn't happen when the placement is to the left.

i.e.:

right placement:

Normal width:

enter image description here

Close to the edge:

enter image description here

left placement:

Normal width:

enter image description here

close to the edge:

enter image description here

These images are from a small DEMO I wrote to illustrate the problem.

I've messed around with the source code, so far to no avail. I can't seem to place my finger on what exactly causes this behavior in the first place.

Any ideas?

p.s.

I'm using Bootstrap 3.1.1. The new 3.2 does not solve the issue (and I would like to avoid upgrading at this point).


Major Update!

After some digging, I figured out that this has nothing to do with bootstrap - it's simple css - it seems that when you position an element absolutely and push it to the sides it will try and stay withing the screen.

I never knew about this behavior, and it happens automatically - but only to the the direction you're pushing - i.e. a div pushed from the left will contract when reaching the right edge of the screen and vice versa.

It just so happens that popovers are only positioned with the left assignment - which is why we're seeing the inconsistend behavior - when it's pushed to the right it contracts but not the other direction.

So the solution is to assign right instead - sounds simple? Not so much. I took the source code and manipulated it a bit, adding these lines (somewhere arond line 250 in the jsfiddle):

if (placement == 'left' && offset.left < 0) {
    var right = ( $(window).width() + 10 ) - ( offset.left + actualWidth ); 

    offset.left = 0;
    $tip.offset(offset);
    $tip.css({ 'right': right });
}

Seems reasonable, right? If the offset to the left is less than 0 (i.e., it goes offscreen) then calculate the window width and remove from that the left offset and the width of the popover (actualWidth) itself and you get the distance from the right.

Then, make sure to reset the offset left and apply the right positioning. But... it only sorta works - which is to say it only works the second time around.

Check it out for yourself! Hover once, and it's misplaced, pull the mouse to the side and try again and suddenly it's positioned correctly. What the hell?

edit

Ok this seems to come up a lot, so I'll make it clear:

I know about auto placement. I don't want it. I want to control where the popover goes, letting it decide automatically is not a solution to the problem, it's merely avoiding it

like image 661
yuvi Avatar asked Jul 15 '14 14:07

yuvi


People also ask

How do I change the position of the tooltip in bootstrap?

In Bootstrap 4, you can position the tooltip in various directions (left, right, top, bottom). The positioning of the tooltip is set by using the third-party library (Popper. js) before bootstrap. js in order for the tooltip to work.

What is the difference between popover and tooltip?

Tooltip: use tooltips to show a short text to respondents when they hover over a word or icon. Popover: use popovers to show a longer text, or when you want to have a link to an external web page. It is shown when the respondent clicks on a word or icon.

How do I change the tooltip position in HTML?

The tooltip text is placed inside an inline element (like <span>) with class="tooltiptext" . CSS: The tooltip class use position:relative , which is needed to position the tooltip text ( position:absolute ). Note: See examples below on how to position the tooltip. The tooltiptext class holds the actual tooltip text.

How do I show popover on hover?

Set the trigger option of the popover to hover instead of click , which is the default one. Or with an initialization option: $("#popover"). popover({ trigger: "hover" });


Video Answer


1 Answers

Ok, I've gotten a little closer.

Once you assign the right in css, the actualWidth and actualHeight will change, so you need to update those variables. Around line 253 in your jsfiddle:

if (placement == 'left' && offset.left < 0) {
    var right = (  $(window).width() + 10) - ( offset.left + actualWidth ); 

    offset.left = 0;
    $tip.offset(offset);
    $tip.css({ 'right': right });
    actualWidth  = $tip[0].offsetWidth;
    actualHeight = $tip[0].offsetHeight;
}

This works the first time you hover, but every time after that, it sets the top to be too high, so you can't read the top of the tooltip.

UPDATE: It appears that having the right value set is messing up the positioning in the applyPlacement function. To fix this, clear the right value before setting the initial actualWidth and actualHeight (around line 225):

$tip.css({ 'right': '' });
// check to see if placing tip in new offset caused the tip to resize itself
var actualWidth  = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
like image 200
AJ Richardson Avatar answered Sep 30 '22 15:09

AJ Richardson