How do you makes "emoji as a letter" accessible?
I have some logo text that includes the word "đź’ˇdea" - what would be the best way to write this?
18 Replies
My initial thought is to have the emoji in a
::before
pseudo element so it’s not read by screen readers. Then have a hidden span with the I
so it’s not seen by the eyes but a screen reader can read it
-# (Note the lack of space between I
and dea
)Sounds kinda... silly but how would I hide it but ensure that the text remains centered(-ish)? Here's the current component that I have:
Something like this:
Made a codepen but on my phone so codepen isn’t logged in so I can’t share the pen
all good, got the idea!
Would a word that has it's letters split up by spans be accessible? Wouldn't a screen reader see that as 2 separate entities?
This is a little fiddley. It is consistent across a single font-family, but if you changed the font-family you would need to change the
ch
value. The advantage of this method would be that a screen reader would read the word properly.
Also if you didn't want the screen reader to read the emoji you could put it in a before element instead.
and if you want to keep the lightbulb in the HTML, and not potentially have a ton of classes just because you want a dozen different emoji in your text:
any span that doesn't have
--content
set will just not have a ::before
You have a beautiful, beautiful brain
You would have to be careful with nested spans and also you do not have a way to "eat" the first character if you put the emoji in the span.
hmm, but you could adapt using style to set the content to use your version
I dislike hardcoding something that should be in HTML in CSS, because now all of a sudden you have to update two files if you just want to change some text, and if that text is in the database, now to update it you have to deploy something new rather than just update a field in a CMS backend
Yes with the caveat that nested components (which is super unlikely) would still have --content set.
you could use this
to solve that
I do not disagree but it may be a better use case for attr than a custom property
that could definitely work too
I came up with something similar using the
::first-letter
selector to make the "I" transparent as you can't actually hide a letter using this selector as far as I am aware.
The only thing I don't like about it is the magic number to position the icon where the "I" would be.
Note, I did just modify it to use a data attribute for the icon as that seemed like a great idea, I originally had it hard-coded as the content.you could set the font-size to 0 or something maybe?
@Jochem font-size: 0 works well. Just tested in a code pen
https://codepen.io/caldane/pen/XWvXLob
The nested spans are still necessary to so you don't end up targeting the emoji with the first-letter selector. @Chris solved this by making it position absolute, but then you have to position the emoji (which was possible with right: 100%). This way doesn't require jumping out of the stacking context, which has some value.
The display flex and align-items is to force the text and emoji to have the same lower bounds.
The line height is a bit of a hack but it allows for the emoji to look like it is on the same baseline as the text.
With everyone's suggestion implemented in this version I find it to be a rather elegant solution to an interesting problem.
oh wow, I come back after a while and.. damn.
thanks <3