Robbert
Robbert

Reputation: 1330

Position bottom element of top parent element

I am making this simple tooltip where I want to position the tooltip bottom at the top of the parent element. I want to do this by getting the height of the tooltip element and set this number negative to the top positioning. The problem is that at the time that I hover the element, the tooltip height is 0, according to console.log();

$('.tooltip').hover(function() {
    var content = $(this).data('tip-content');
    var element	= $(this).find('.tip-content');

    if(element.length == 0 ) {
        var html 	= $('<p class="tip-content">' + content + '</p>');
        var height	= html.height();
        console.log(height);
        html.css('top', - height);
        $(this).prepend(html);
    } else {
        element.remove();
    }
});
.element {
    height: 50px;
    width: 50px;
    margin: 50px auto;
    background: #000;
}

.tooltip {
	position: relative;	
}

.tooltip .tip-content {
	width: 180px;
	margin-left: -98px;
	padding: 10px 5px;
	position: absolute;
	left: 50%;
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	border-radius: 3px;	
	background: #294a72;
	font-size: 0.75em;
	color: #fff;
	text-align: center;
}

.tooltip .tip-content:after {
	top: 100%;
	left: 50%;
	border: solid transparent;
	content: " ";
	height: 0;
	width: 0;
	position: absolute;
	pointer-events: none;
	border-top-color: #294a72;
	border-width: 5px;
	margin-left: -5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="element tooltip" data-tip-content="This is a test content">
</div>

Upvotes: 0

Views: 108

Answers (4)

Knowledge Nybbler
Knowledge Nybbler

Reputation: 46

At the time you're checking the height, the element has not yet been added to the DOM, and therefore can have no height. You simply need to switch the order of your statements. jQuery can and will change the CSS of the element even after it has been added.

var html = $('<p class="tip-content">' + content + '</p>');
$(this).prepend(html);  //This line must go before the next
var height  = html.height();
console.log(height);

However, you're still missing some pieces. height() does not include either margin or padding. To get padding, you can use outerHeight(), but margin you'll have to either read from the CSS or use a hard-coded value. Even worse, your arrow is using a pseudo-element, which *cannot* be read by DOM traversal, so your best bet there is to just hardcode it, sadly.

A better height calculation might look like:

var ARROW_HEIGHT = 5;
html.outerHeight() + parseInt(html.css('marginBottom'), 10) + ARROW_HEIGHT;

Upvotes: 3

Ricardo Rocha
Ricardo Rocha

Reputation: 16216

For html object gets a height automatically, you need first put in DOM. That the reason for you get height = 0. You need first append your object and then get the height.

See my example: https://jsfiddle.net/bwun82q4/

$('.tooltip').hover(function() {
var content = $(this).data('tip-content');
var element = $(this).find('.tip-content');

if(element.length == 0 ) {
    var html    = $('<p class="tip-content">' + content + '</p>');
    var height  = html.height();
    console.log(height);
    html.css('top', - height);
    $(this).prepend(html);

    $(this).find("p").css("top",- $(this).find("p").height());
} else {
    element.remove();
}});

Upvotes: 0

Chitrang
Chitrang

Reputation: 2114

You just need to get height of 'tooltip' instead of 'tip-content'.

$('.tooltip').hover(function() {
    var content = $(this).data('tip-content');
    var element	= $(this).find('.tip-content');

    if(element.length == 0 ) {
        var html 	= $('<p class="tip-content">' + content + '</p>');
        // Get height of parent element
        var height	= $(this).height();
        console.log(height);
        html.css('top', - height);
        $(this).prepend(html);
    } else {
        element.remove();
    }
});
.element {
    height: 50px;
    width: 50px;
    margin: 50px auto;
    background: #000;
}

.tooltip {
	position: relative;	
}

.tooltip .tip-content {
	width: 180px;
	margin-left: -98px;
	padding: 10px 5px;
	position: absolute;
	left: 50%;
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	border-radius: 3px;	
	background: #294a72;
	font-size: 0.75em;
	color: #fff;
	text-align: center;
}

.tooltip .tip-content:after {
	top: 100%;
	left: 50%;
	border: solid transparent;
	content: " ";
	height: 0;
	width: 0;
	position: absolute;
	pointer-events: none;
	border-top-color: #294a72;
	border-width: 5px;
	margin-left: -5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="element tooltip" data-tip-content="This is a test content">
</div>

Upvotes: 0

Ragdoll
Ragdoll

Reputation: 335

I think you have to prepend the HTML, and then get the height and reposition the element. Right now, you are getting the height of a variable, not an HTML element.

Upvotes: 0

Related Questions