Block links, the inclusive way
The whole card is clickable, yet there's still only one real, keyboard-focusable link.
Example of a fade modal with a close button. Don't like the position? Use the action buttons below.
TODO:
is-screen-smHover this text to see the highlight swap sides (desktop only).
A gradient `background-image` behind the text acts as the marker. `.-animate` clips it to the text on hover (`background-clip: text`) and slides it in/out by transitioning `background-size`/`background-position` - `.-active` flips which side it starts from.
MDN - background-clip| Header 1 | Header 2 | Header 3 |
|---|---|---|
| Row 1, Cell 1 | Row 1, Cell 2 | Row 1, Cell 3 |
| Row 2, Cell 1 | Row 2, Cell 2 | Row 2, Cell 3 |
This prevent extra space between table cells and ensures that if a border is applied, it will be shown.
.m-table {
table-layout: fixed;
border-collapse: collapse;
width: 100%;
}
HTML Table Element Guide (Chris Coyier on Aug 12, 2024)
<div class="parallax height-quarter">
<div class="parallax-back height-screen">
<div class="dice" style="--top: 95%; --left: 50%"></div>
<div class="dice" style="--top: 30%; --left: 1%"></div>
<div class="dice" style="--top: 60%; --left: 29%"></div>
<div class="dice" style="--top: 30%; --left: 80%"></div>
<div class="dice" style="--top: 35%; --left: 35%"></div>
<div class="dice" style="--top: 12%; --left: 90%"></div>
<div class="dice" style="--top: 145%; --left: 90%"></div>
<div class="dice" style="--top: 120%; --left: 90%"></div>
<div class="dice" style="--top: 102%; --left: 90%"></div>
</div>
<div class="parallax-content">
<p class="lorem">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</p>
</div>
</div>
Hover the square: a `@keyframes shake` runs on `:hover`, nudging `transform: translate3d()` back and forth. On the homepage the same SVG is also wired to a checkbox that shakes the entire page as an easter egg - here it's just the self-contained hover trick.
.shake__shape:hover {
animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
@keyframes shake {
10%, 90% { transform: translate3d(-1px, 0, 0); }
20%, 80% { transform: translate3d(2px, 0, 0); }
30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
40%, 60% { transform: translate3d(4px, 0, 0); }
}
CSS-Tricks - Shake CSS AnimationThe whole card is clickable, yet there's still only one real, keyboard-focusable link.
Try tabbing through both cards - only the title link and the author link receive focus.
Only the card title is a real `<a>`. An absolutely positioned `::after` on that link stretches to the card's edges, making the whole card clickable while keeping exactly one focusable target. Any secondary link (like the author) just needs `position: relative` and a higher `z-index` to stay reachable above it.
.m-card { position: relative; }
.m-card__link::after {
content: '';
position: absolute;
inset: 0;
}
.m-card__meta a { position: relative; z-index: 1; }
Inclusive Components - CardsA checkbox + `label[for]` opens/closes the modal; `:has()` on the wrapper locks page scroll while open.
Prevent Page Scrolling When a Modal is OpenSame open/close trick as the modal, in a side panel. The checkbox's native tick color comes from `accent-color` instead of a custom-built control.
CSS-Tricks - accent-color