I have prepared a complete example demonstrating my problem:
My context is: in a 2-columns table I would like to show a list of players on the left and a game with 2-players on the right.
To display a player I have prepared a jQuery UI widget based on a div
with CSS position: relative;
and it works well in list of players on the left side.
However on the right side I am trying to use the same widget twice with CSS position: absolute;
and for some reasons the "Ms. Left" and "Mr. Right" are positioned as if their parent would be the body
and not the #gameTd
.
Why does it happen please and how to position the 2 divs relatively to the #gameTd
?
HTML:
<table border="1" width="100%">
<tr>
<th>Lobby</th>
<th>Game</th>
</tr>
<tr>
<td id="lobbyTd"></td>
<td id="gameTd">
<div id="leftPlayer"></div>
<div id="rightPlayer"></div>
</td>
</tr>
</table>
CSS:
#lobbyTd {
width: 25%;
overflow-y: scroll;
}
#gameTd {
background: #6C6;
}
.my-player {
position: relative;
background: #FFF no-repeat center;
background-size: contain;
box-shadow: 0 0 32px rgba(0, 0, 0, 0.2);
margin: 8px;
width: 160px;
height: 120px;
}
.my-player-name {
position: absolute;
font-size: 18px;
background: #FFF;
color: #000;
left: 0;
bottom: 0;
padding: 2px;
width: 154px;
height: 20px;
}
Javascript:
jQuery(document).ready(function($) {
var PHOTO_PATTERN = /^https?:\/\/\S+/i;
$.widget('my.player', {
// default options
options: {
name: '',
photo: 'https://slova.de/raspasy/images/male_happy.png',
},
_create: function() {
this._hoverable(this.element);
this.element.addClass('my-player');
this.nameDiv = $('<div/>', {
'class': 'my-player-name'
}).appendTo(this.element);
this._refresh();
},
_destroy: function() {
this.nameDiv.remove();
this.element.removeClass('my-player');
},
_setOptions: function() {
this._superApply(arguments);
this._refresh();
},
_refresh: function() {
var photo = (PHOTO_PATTERN.test(this.options.photo) ? this.options.photo : 'https://slova.de/raspasy/images/male_happy.png');
this.element.css('background-image', 'url("' + photo + '")');
this.nameDiv.text(this.options.name);
}
});
var lobbyPlayer1 = $('<div/>').player({
name: 'Player #1'
}).appendTo($('#lobbyTd'));
var lobbyPlayer1 = $('<div/>').player({
name: 'Player #2',
photo: 'https://slova.de/raspasy/images/female_sad.png'
}).appendTo($('#lobbyTd'));
var lobbyPlayer3 = $('<div/>').player({
name: 'Alexander',
photo: 'http://afarber.de/images/farber.jpg'
}).appendTo($('#lobbyTd'));
// Why is absolute positioning wrong below?
var leftPlayer = $('#leftPlayer').player({
name: 'Ms. Left',
photo: 'https://slova.de/raspasy/images/female_happy.png'
}).css({
position: 'absolute',
left: '30px',
top: '20px'
});
var rightPlayer = $('#rightPlayer').player({
name: 'Mr. Right',
photo: 'https://slova.de/raspasy/images/male_sad.png'
}).css({
position: 'absolute',
right: '30px',
top: '20px'
});
});
You need to add position: relative
for #gameTd
for positioning relative to this block.