I am trying to create a tooltip element that has a min width of 50px and a max width of 200px. I place the tooltip element inside another element so that I can easily control when the tooltip appears or disappears when there is a hover event on the parent.
The problem that I have is that the tooltip element's width appears to be controlled by the parent's width even though I specified that the child(tooltip) has an absolute position.
let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
b = !b;
let w = 10;
if( b ) {
w = 300;
}
p.style.width = `${w}px`
}, 5000 );
#parent {
background-color: cyan;
width: 100px;
height: 25px;
position: relative;
transition: width 2s;
}
#tooltip {
position: absolute;
top: calc( 100% + 5px );
left: 5px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="parent">
<div id="tooltip">
My long tooltip text that wraps to multiple lines as needed.
</div>
</div>
I would like the tooltip (yellow div) to keep it's size at 200px in this example, but we can see that when the parent changes width, the tooltip width also changes. Why?
Is there a way to fix this problem?
Clarification: In this example: https://codepen.io/anon/pen/ePPWER we see that the tooltip text looks nice on one line. I don't want the tooltip's div to change its width when the parent changes width, because it forces the tooltip text to wrap onto 2 lines which is undesirable.
If we check the specification related to the width of absolutely positioned element we can read this:
- 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
So in your case the width of your element is shrink to fit:
Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, calculate the available width: this is found by solving for 'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.
Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
To make it easy, and without considering the min/max-width, the width of your element will try to fit the content without exceding the width of its parent container (containing block). By adding min/max-width you simply add more constraint.
One idea of fix it to remove positon:relative
from the parent element so that it's no more the containing block of the position:absolute
element (it will be the initial containing block which is wide enough to avoid the available width constraint).
Then use margin instead of top/left to control the position:
let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
b = !b;
let w = 10;
if( b ) {
w = 300;
}
p.style.width = `${w}px`
}, 5000 );
#parent {
background-color: cyan;
width: 100px;
height: 25px;
transition: width 2s;
}
#tooltip {
position: absolute;
margin-top: 30px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="parent">
<div id="tooltip">
My long tooltip text that wraps to multiple lines as needed.
</div>
</div>