JSFiddle - React, Tailwind, and code Playground
by shin1974
HTML
<!-- 1. Working area -->
<div id="working_area">
<!-- 1. (1) Sandbox + (2) Pseudo-elements -->
<div id="sandbox"></div>
<div>
<!-- 1. (3) Annotation -->
<div id="annotation">Please click inside the sandbox or the buttons.</div>
<!-- 1. (4) Results -->
<fieldset id="results">
<legend>Results</legend>
<div><span>Cursor: </span><span id="cursor_position"></span></div>
<div><span>Clicked: </span><span id="clicked_point"></span></div>
<div id="message"></div>
</fieldset>
</div>
</div>
<!-- 2. Info area -->
<fieldset id="info_area">
<legend>Info</legend>
<div class="title">Actual coordinates and size of pseudo-elements</div>
<div id="items">
<!-- 2. (1) Info of :before pseudo-element -->
<div class="item">
<div>:before</div>
<div id="bp_info"></div>
</div>
<!-- 2. (2) Info of :after pseudo-element -->
<div class="item">
<div>:after</div>
<div id="ap_info"></div>
</div>
</div>
</fieldset>
CSS
* {
box-sizing: border-box;
}
body {
margin: 0;
font-size: 14px;
}
/**
* 1. Working area
*/
#working_area {
display: flex;
}
/**
* 1. (1) Sandbox
*/
#sandbox {
position: relative;
min-width: 100px;
max-width: 100px;
min-height: 100px;
max-height: 100px;
border-bottom: 1px dashed #888;
border-right: 1px dashed #888;
background: #ffa;
}
/**
* 1. (2) Pseudo-elements
*/
#sandbox:before,
#sandbox:after {
position: absolute;
width: 60px;
height: 25px;
display: flex;
justify-content: center;
align-items: center;
border: 2px solid #aaa;
border-radius: 4px;
background: #ddd;
cursor: pointer;
}
#sandbox:before {
content: ":before";
top: 10px;
left: 10px;
}
#sandbox:after {
content: ":after";
bottom: 10px;
right: 10px;
}
/**
* 1. (3) Annotation
*/
#annotation {
padding-top: 5px;
text-align: center;
font-weight: bold;
text-decoration: underline;
}
/**
* 1. (4) Results
*/
#results {
width: 400px;
height: 100px;
margin: 5px 10px;
}
/**
* 2. Info area
*/
#info_area {
margin: 0 10px;
width: 500px;
}
.title {
text-align: center;
font-weight: bold;
text-decoration: underline;
padding-bottom: 10px;
}
#items {
display: flex;
gap: 10px;
}
.item {
width: 230px;
border: 1px solid #aaa;
padding: 5px;
}
/**
* 2. (1) Info of :before pseudo-element
* (2) Info of :after pseudo-element
*/
#bp_info,
#ap_info {
padding-left: 15px;
}
JavaScript
$(() => {
const $sandbox = $('#sandbox');
const sandbox = $sandbox[0];
/**
* Adds mouse move event listener.
*/
$sandbox.mousemove((e) => {
$('#cursor_position').text('(x: ' + e.pageX + ', y: ' + e.pageY + ')');
});
/**
* Adds click event listener.
*/
$sandbox.click((e) => {
// shows the coordinates of clicked point
$('#clicked_point').text('(x: ' + e.pageX + ', y: ' + e.pageY + ')');
// mouse cursor position
const mousePoint = { x: e.pageX, y: e.pageY };
if (isMouseOnPseudoElement(mousePoint, e.target, 'before')) {
$('#message').text('[:before] pseudo-element was clicked!!!').css('color', 'blue');
} else if (isMouseOnPseudoElement(mousePoint, e.target, 'after')) {
$('#message').text('[:after] pseudo-element was clicked!!!').css('color', 'blue');
} else {
$('#message').text('An area outside the pseudo-element was clicked...').css('color', 'red');
}
});
/**
* Shows the actual coordinates and size of pseudo-elements.
*/
(() => {
const bpRect = getPseudoElementRect(sandbox, 'before');
const apRect = getPseudoElementRect(sandbox, 'after');
const $bp_root = $('#bp_info');
$('<div>').text(`top left: (x: ${ bpRect.left}, y: ${bpRect.top})`).appendTo($bp_root);
$('<div>').text(`bottom right: (x: ${bpRect.right}, y: ${bpRect.bottom})`).appendTo($bp_root);
$('<div>').text(`width: ${bpRect.right - bpRect.left}, height: ${bpRect.bottom - bpRect.top}`).appendTo($bp_root);
const $ap_root = $('#ap_info');
$('<div>').text(`top left: (x: ${ apRect.left}, y: ${apRect.top})`).appendTo($ap_root);
$('<div>').text(`bottom right: (x: ${apRect.right}, y: ${apRect.bottom})`).appendTo($ap_root);
$('<div>').text(`width: ${apRect.right - apRect.left}, height: ${apRect.bottom - apRect.top}`).appendTo($ap_root);
})();
});
/**
* Gets the rectangle info of the pseudo-element.
*
* @param {DOMElement} element: root element
* @param {String} pseudoType: "before" or "after"
* @returns {JSON}: rectangle info of...