JSFiddle - React, Tailwind, and code Playground
HTML
<div id="labelzone">
<div class="label" style="left:0%;top:8%">001</div>
<div class="label" style="left:0%;top:8%">002</div>
<div class="label" style="left:1%;top:10%">003</div>
</div>
CSS
#labelzone {
float:left;
width:500px;
height:500px;
border: 1px solid black;
position: relative;
}
.label {
position:absolute;
border:1px solid black;
background-color:white;
}
JavaScript
var Label = function ($el) {
var position = $el.position(),
width = $el.outerWidth(true),
height = $el.outerHeight(true);
this.getRect = function () {
return {
x: position.left,
y: position.top,
width: width,
height: height
};
};
this.modifyPos = function (modX, modY) {
position.top += modY;
position.left += modX;
updatePos();
};
function updatePos() {
$el.css({
top: position.top,
left: position.left
});
}
};
var LabelPool = function () {
var labelPool = [];
function collides(a, b) {
return !(((a.y + a.height) < (b.y)) || (a.y > (b.y + b.height)) || ((a.x + a.width) < b.x) || (a.x > (b.x + b.width)));
}
function overlaps(label) {
var a = label.getRect();
return labelPool.some(function (other) {
return collides(a, other.getRect());
});
}
this.accomodate = function (label) {
while (labelPool.length && overlaps(label)) {
label.modifyPos(0, 1);
}
labelPool.push(label);
};
};
var labelPool = new LabelPool;
$(".label").each(function (_, el) {
labelPool.accomodate(new Label($(el)));
});