CSS callout connectors
by secretgspot
HTML
<link rel="stylesheet" href="http://static.maklarpaket.se/css/jquery-ui-custom.css">
<div id="anchor"></div>
<div class="ui-tooltip ui-tooltip-arrow-tc ui-widget ui-widget-content ui-corner-all">
Drag me around the gray box
<div class="ui-tooltip-arrow">
<div class="ui-tooltip-arrow-fill">
</div>
</div>
</div>
CSS
body, html {
font-size: 14px;
font-family: Arial;
}
#anchor {
position: absolute;
height: 50px;
width: 50px;
border: 1px solid #666666;
left: 45%;
top: 45%;
background-color: #ccc;
}
.ui-tooltip {
padding: 8px;
position: absolute;
z-index: 9998;
-o-box-shadow: 2px 2px 2px #ccc;
-moz-box-shadow: 2px 2px 2px #ccc;
-webkit-box-shadow: 2px 2px 2px #ccc;
box-shadow: 2px 2px 2px #ccc;
background: rgba(255,255,255,80);
min-width: 100px;
max-width: 200px;
}
.ui-tooltip-arrow {
border-color: transparent;
border-style: solid;
border-width: 9px;
height:0;
width:0;
position: absolute;
}
/* IE6 */
* .ui-tooltip-arrow {
_border-left-color: pink;
_border-bottom-color: pink;
_border-right-color: pink;
_filter: chroma(color=pink);
}
.ui-tooltip-arrow-fill {
border-color: transparent;
border-style: solid;
border-width: 9px;
height: 0;
width: 0;
position: absolute;
left: -9px;
bottom: -9px;
}
.ui-tooltip-arrow-tc .ui-tooltip-arrow {
border-bottom-color: #666666;
top: -19px;
left: 100px;
}
.ui-tooltip-arrow-tc .ui-tooltip-arrow-fill {
border-bottom-color: #ffffff;
bottom: -10px;
}
.ui-tooltip-arrow-tr .ui-tooltip-arrow,
.ui-tooltip-arrow-tr .ui-tooltip-arrow-fill {
border-right-width: 18px;
border-top-width: 11px;
border-bottom-width: 0;
}
.ui-tooltip-arrow-tr .ui-tooltip-arrow {
border-right-color: #666666;
top: -12px;
left: 80%;
}
.ui-tooltip-arrow-tr .ui-tooltip-arrow-fill {
border-right-width: 17px;
border-top-width: 10px;
border-right-color: #ffffff;
bottom: -1px;
left: -9px;
}
.ui-tooltip-arrow-tl .ui-tooltip-arrow,
.ui-tooltip-arrow-tl .ui-tooltip-arrow-fill {
border-left-width: 18px;
border-top-width: 11px;
border-bottom-width: 0;
}
.ui-tooltip-arrow-tl .ui-tooltip-arrow {
border-left-color: #666666;
top: -12px;
left:...
JavaScript
// refactor: merge getY and getX into one function - the calculations are the same, just t/b vs. l/r
function getY(y1, y1u, y2, y2u) {
var retVal, ori;
if(y2 > y1 && y2u < y1u){
retVal = y1 + (y2-y1) + 0.5*(y2u-y2);
ori = "c";
}else if(y2 < y1 && y2u > y1u) {
retVal = y1 + 0.5*(y1u - y1);
ori = "c";
}else if(y2 > y1 && y2u > y1u){
retVal = y1u - 0.5*(y1u - y2);
ori = "b";
}else{
retVal = y1 + 0.5*(y2u-y1);
ori = "t";
}
return ({
cutY : retVal,
orientation: ori
});
};
function getX(x1,x1r,x2,x2r){
var retVal, ori;
if(x2 > x1 && x2r < x1r){
retVal = x1 + (x2-x1) + 0.5*(x2r-x2);
ori = "c";
}else if(x2 < x1 && x2r > x1r) {
retVal = x1 + 0.5*(x1r - x1);
ori = "c";
}else if(x2 > x1 && x2r > x1r){
retVal = x1r - 0.5*(x1r - x2);
ori = "r";
}else{
retVal = x1 + 0.5*(x2r-x1);
ori = "l";
}
return ({
cutX : retVal,
orientation: ori
});
};
function calc(x1, y1, w1, h1, x2, y2, w2, h2, offsetX, offsetY) {
// corners
var cutX = 0,
cutY = 0,
orientation = "lt";
var x1r = x1 + w1;
var y1u = y1 + h1;
var x2r = x2 + w2;
var y2u = y2 + h2;
// right
if(x2 > x1r){
// below --> cornerarrow
if(y2 > y1u){
orientation = "br";
offsetX = 0;
offsetY += 4;
cutX = x1r - 4;
cutY = y1u;
}
// above --> cornerarrow
else if(y1 > y2u){
orientation = "tr";
offsetX = 0;
offsetY -= 26;
cutX = x1r - 10;
cutY = y1;
}
// right --> centerarrow
else{
offsetX += 4;
offsetY = 0;
cutX = x1r;
var vals = getY(y1,y1u,y2,y2u);
cutY = vals.cutY;
orientation = "r" +...