'Use CSS to create a drop cap as an image (with accessibility)
There are plenty of guides online explaining how to do drop caps in HTML and CSS, e.g. https://css-tricks.com/snippets/css/drop-caps/ (They typically require a bit of care not to break screen-reader accessibility, e.g. splitting the word "Carol" into "C arol.")
But all of the online guides I've found discuss how to style the :first-letter
, e.g. changing its font, floating left, etc.
My designer has asked me to create a drop cap that's an image, not just a different size/font.
My first attempt was this:
<p><img src="c.jpg" alt="C" style="float: left;">arol
But screen readers read that as two words, "C arol," instead of one word, "Carol."
What's the best way to handle this?
Solution 1:[1]
You could use the fact that a first-letter pseudo element can have a background image and set the first letter itself to transparent so that it isn't seen, but a screen reader shouldn't notice as the basic HTML remains intact.
p.dropcapimg::first-letter {
background-image: url(https://i.stack.imgur.com/WecKn.png);
background-size: contain;
background-repeat: no-repeat;
background-center: center center;
float: left;
font-size: 6rem;
line-height: 0.65;
color: transparent;
margin-right: -0.15em;
}
<p class="dropcapimg">Carol a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text
now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text now a lot of text
now a lot of text now a lot of text now </p>
Obviously you'll need to fiddle around with sizes depending on the actual image.
Solution 2:[2]
My approach was to insert the <img>
with aria-hidden=true
, so screen readers would ignore it, and to style the first letter with visibility: hidden
, so it would visually read as one word.
p img {
float:left;
}
p::first-letter {
visibility: hidden;
}
<p><img src="https://freesvg.org/img/ryanlerch-Decorative-Letter-Set-4.png" height="50" width="50" aria-hidden="true">Carol</p>
Solution 3:[3]
IN any case, you won't be able to join in the "C" present in alt and the following "arol" so that the screen reader consider it as a single word. This is simply impossible. You may use aria-label, but since it isn't on an interactive element, it may not work everywhere, and you must be careful to not replace the whole paragraph.
A possibility could be a combination of visually hidden text and aria-hidden, like this:
<p>
<span aria-hidden="true"><img src="C.jpg"/>arol</span>
<span class="sr_only">Carol</span>
normal text following
</p>
Where .sr_only is a special class that sends the text off screen, such that you won't see it but screen readers will. Bootstrap proposes such a class for example.
Note that, using an image as a first letter decoration is not only a bad idea for screen readers users as you have noticed it, but also for partially sighted people, since it prevents them from properly zooming (because of resize artifacts) or adapting text colors to their needs. It's also probably a bad idea for SEO, as the name "Carol" might not be indexed as well as it was written plain text. For constrained connections, an image is also probably bigger than a font that has great chances to be reused on many sites (and so already downloaded). Well, there are only disadvantages in fact.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | A Haworth |
Solution 2 | Dan Fabulich |
Solution 3 | QuentinC |