JSFiddle - React, Tailwind, and code Playground
by saenas
HTML
<body>
<a href="#" onfocus="showAcronymToggle();">Skip to content</a>
<div id="acronymToggle">
<input type="checkbox" id="switch1" name="switch1" class="switch" onclick="toggleAcronyms();" />
<label for="switch1">Expand abbreviations: off/on</label>
</div>
<h1>Keyboard access to acronyms</h1>
<p>
Lorem ipsum dolor sit <abbr title="Deutsches Institut für medizinische Dokumentation und Information">DIMDI</abbr> consetetur sadipscing elitr, Lorem ipsum dolor si <abbr title="Operationen und Prozeduren">OPS</abbr> consetetur sadipscing elitr.
</p>
</body>
CSS
/* abbr:focus::after{
content: " (" attr(title) ") ";
position:absolute;
left:-10000px;
top:auto;
width:1px;
height:1px;
overflow:hidden;
} */
span {
position: relative;
}
span.acronymBoxes{
position: absolute;
background-color: #FFBC91;
top: -3ex;
left: 0;
text-align: center;
display: inline-block;
border: 1px solid black;
}
#acronymToggle {
display:none;
}
input.switch:empty {
margin-left: -9999px;
}
input.switch:focus ~ label {
border: 1px dotted black;
}
input.switch:empty ~ label {
position: relative;
float: right;
line-height: 1.6em;
text-indent: -13em;
margin: 0.2em 0;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
input.switch:empty ~ label:before,
input.switch:empty ~ label:after {
position: absolute;
display: block;
top: 0;
bottom: 0;
left: 0;
content: ' ';
width: 3.6em;
background-color: #FF9900;
border-radius: 0.3em;
box-shadow: inset 0 0.2em 0 rgba(0,0,0,0.3);
-webkit-transition: all 100ms ease-in;
transition: all 100ms ease-in;
}
input.switch:empty ~ label:after {
width: 1.4em;
top: 0.1em;
bottom: 0.1em;
margin-left: 0.1em;
background-color: #fff;
border-radius: 0.15em;
box-shadow: inset 0 -0.2em 0 rgba(0,0,0,0.2);
}
input.switch:checked ~ label:before {
background-color: #00CCFF;
}
input.switch:checked ~ label:after {
margin-left: 2em;
}
JavaScript
// Wrap an HTMLElement around each element in an HTMLElement array.
HTMLElement.prototype.wrap = function(elms) {
// Convert `elms` to an array, if necessary.
if (!elms.length) elms = [elms];
// Loops backwards to prevent having to clone the wrapper on the
// first element (see `child` below).
for (var i = elms.length - 1; i >= 0; i--) {
var child = (i > 0) ? this.cloneNode(true) : this;
var el = elms[i];
// Cache the current parent and sibling.
var parent = el.parentNode;
var sibling = el.nextSibling;
// Wrap the element (is automatically removed from its current
// parent).
child.appendChild(el);
// If the element had a sibling, insert the wrapper before
// the sibling to maintain the HTML structure; otherwise, just
// append it to the parent.
if (sibling) {
parent.insertBefore(child, sibling);
} else {
parent.appendChild(child);
}
}
};
function createAcronymBox() {
var title = this.getAttribute("title");
var box = document.createElement('span');
box.className = 'acronymBoxes';
box.innerHTML = title;
box.style.width = title.length*7.5+"px";
this.parentNode.appendChild(box, this.nextSibling);
}
function destroyAcronymBox(active) {
this.nextElementSibling.remove();
}
function addAcronymListeners() {
var acronyms = document.getElementsByTagName("abbr");
for (var i = 0; i < acronyms.length; i++) {
acronyms[i].addEventListener("focus", createAcronymBox, false);
acronyms[i].addEventListener("blur", destroyAcronymBox, false);
}
}
function showAcronymToggle() {
document.getElementById("acronymToggle").style.display = "block";
}
function toggleAcronyms() {
var toggle = document.getElementById("switch1");
var acronyms = document.getElementsByTagName("abbr");
if (toggle.checked) {
for (var i = 0; i < acronyms.length; i++) {
var span =...