JSFiddle - React, Tailwind, and code Playground
HTML
<a href='#' id='tester'>Click Me!</a>
<div id='test-callout' class='callout'>
This is my callout text.
</div>
CSS
body {
font-family: Arial, sans-serif;
color: #666;
}
a {
border: 1px solid #666;
border-radius: 0.5em;
background: #CC9;
color: #333;
padding: 0.5em;
text-decoration: none;
}
.callout {
position: absolute;
z-index: 1;
top: 4em;
left: 2em;
}
.callout-main {
width: 10em;
height: 1em;
padding: 0.5em;
border-radius: 0.5em;
border: 1px solid #666;
background: #FFC;
}
.callout-arrow-left {
position: absolute;
z-index: 2;
top: 0.5em;
left: -0.5em;
border-top: 0.5em solid transparent;
border-bottom: 0.5em solid transparent;
border-right: 0.5em solid #666;
}
.callout-arrow-right {
position: absolute;
z-index: 2;
top: 0.5em;
left: 11em;
border-top: 0.5em solid transparent;
border-bottom: 0.5em solid transparent;
border-left: 0.5em solid #666;
}
JavaScript
var $tester = $('#tester'),
$callout = $('#test-callout');
var CalloutObject = function($callout) {
var pub = {};
pub.isLeft = false;
pub.$callout = $callout;
init()
pub.bindToLink = function($link) {
$link.click(function(e) {
e.preventDefault();
pub.isLeft = !pub.isLeft;
rebuildArrow(pub.isLeft);
});
};
function init() {
$callout.wrapInner('<div class="callout-main" />');
calculateArrow();
}
// ...Dramatic simplification of what I'm up to...
function rebuildArrow(isLeft) {
pub.isLeft = isLeft;
removeArrow();
calculateArrow();
}
function removeArrow() {
var selectors = [
'.callout-arrow-left',
'.callout-arrow-right'
];
pub.$callout.children(selectors.join(',')).remove();
}
// There are actually multiple cases beyond just 'left' and 'right';
// I am working on a full 8-point system.
function calculateArrow() {
var arrowClass;
if(pub.isLeft) {
arrowClass = 'callout-arrow-left';
} else {
arrowClass = 'callout-arrow-right';
}
pub.$callout.append('<div class="' + arrowClass + '"></div>');
}
return pub;
};
$(document).ready(function () {
var testCallout = new CalloutObject($callout);
testCallout.bindToLink($tester);
});