Accessible Clickable Area
by _sir
HTML
<div class="actionable" data-click-area-expanded>
<p>
So much content
that it's not funny
</p>
<p>
<a href="#" class="learnMore">Learn More</a>
</p>
<label for="buttonBlue" class="sr-only">View Details for Check 844</label>
<button id="buttonBlue" class="viewDetail" data-click-area-target="true">
→
</button>
</div>
<div class="actionable" data-click-area-expanded>
<p>
So much content
that it's not funny
</p>
<button class="info learnMore">
ℹ️
</button>
<label for="buttonRed" class="sr-only">View Details for Check 123</label>
<button id="buttonRed" class="viewDetail" data-click-area-target="true">
<span>»</span>
</button>
</div>
CSS
div.actionable {
margin: 1em;
padding: 1em;
border: solid gray;
border-width: 1px 0;
height: 4em;
position: relative;
}
.actionable button.viewDetail {
background: steelblue;
color: white;
font-weight: bold;
font-size: 2rem;
position: absolute;
border: none;
height: 100%;
top: 0;
right: 0;
}
button.info {
border: none;
background: none;
}
#buttonBlue {
background: steelblue;
color: white;
}
#buttonRed {
background: maroon;
color: white;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: none;
}
JavaScript
document.getElementById('buttonBlue').addEventListener('click', () => console.log('We clicked the blue button!'));
document.getElementById('buttonRed').addEventListener('click', () => console.log('We clicked the red button!'));
[...document.querySelectorAll('.learnMore')].forEach(el => el.addEventListener('click', () => console.log('Learn more!')));
const clickableElemTypes = ['a', 'button', 'input'];
[...document.querySelectorAll('[data-click-area-expanded]')].forEach((container) => {
container.addEventListener('click', (e) => {
const targets = [...container.querySelectorAll('[data-click-area-target]')];
if (targets.length !== 1) {
throw new Error('Could not find single click target');
}
const [actionTarget] = targets;
const clickables = [...container.querySelectorAll('a,button,input')];
const inClickable = clickables.some((el) => el.contains(e.target));
if (inClickable) {
return;
}
console.log('Passing the action from the click area.');
actionTarget.click();
});
});