Bad code
Letters are wrapped in div
s to animate each letter with JavaScript.
<h3>
<div style="display: block; text-align: start; position: relative;" class="title">
<div style="position: relative; display: inline-block; transform: rotateX(90deg); transform-origin: 50% 50% -30.8917px;" class="char">H</div>
<div style="position: relative; display: inline-block; transform: rotateX(90deg); transform-origin: 50% 50% -30.8917px;" class="char">e</div>
<div style="position: relative; display: inline-block; transform: rotateX(90deg); transform-origin: 50% 50% -30.8917px;" class="char">a</div>
<div style="position: relative; display: inline-block; transform: rotateX(90deg); transform-origin: 50% 50% -30.8917px;" class="char">d</div>
<div style="position: relative; display: inline-block; transform: rotateX(90deg); transform-origin: 50% 50% -30.8917px;" class="char">i</div>
<div style="position: relative; display: inline-block; transform: rotateX(90deg); transform-origin: 50% 50% -30.8917px;" class="char">n</div>
<div style="position: relative; display: inline-block; transform: rotateX(90deg); transform-origin: 50% 50% -30.8917px;" class="char">g</div>
</div>
</h3>
Issues and how to fix them
Assistive technology may announce the word letter by letter, if each letter is wrapped in an element.
Code for this demoTry to avoid excessive DOM sizes. Too many DOM nodes and nested DOM elements may harm your page performance.
A large DOM tree results in a large accessibility tree, which may have a bad impact on the performance of assistive technology.
The separation of presentation from content is advised. Move styles that don’t change dynamically into a CSS file.
Good code (Solution 1)
<h3> Heading </h3>
Good code (Solution 2)
If you really have to.
Provide an accessible version of the text for screen readers and hide the inaccessible text by using aria-hidden="true"
.
<h3 class="title">
<span class="sr-only">Heading</span>
<div aria-hidden="true">
<div style="transform-origin: 50% 50% -30.8917px;" class="char">H</div>
<div style="transform-origin: 50% 50% -30.8917px;" class="char">e</div>
<div style="transform-origin: 50% 50% -30.8917px;" class="char">a</div>
<div style="transform-origin: 50% 50% -30.8917px;" class="char">d</div>
<div style="transform-origin: 50% 50% -30.8917px;" class="char">i</div>
<div style="transform-origin: 50% 50% -30.8917px;" class="char">n</div>
<div style="transform-origin: 50% 50% -30.8917px;" class="char">g</div>
</div>
</h3>
Unfortunately, there’s no native way of hiding content only visually.
The .sr-only
class makes sure that content is visually hidden but still accessible to screen reader users.
.title { display: block; text-align: start; position: relative; }
.char { position: relative; display: inline-block; transform: rotateX(90deg); }
.sr-only { position: absolute; white-space: nowrap; width: 1px; height: 1px; overflow: hidden; border: 0; padding: 0; clip: rect(0 0 0 0); clip-path: inset(50%); margin: -1px; }