Work Text:
This is some text messaging chat code I wrote for my good friend NobodyInParticular123456!
Some features included in how it's set up:
- The width flexes with the browser when it gets narrow, so it's mobile friendly!
- The whole thing will smoothly scale in size to match the reader's font settings.
- It has hidden text to label who is talking so it will be screen-reader friendly for our blind and low-vision readers, or if someone has workskins disabled. 💜
- The colors were chosen to look nice and stay readable on both light and dark backgrounds. Don't forget that not everyone uses the same theme as you, and forcing a theme upon someone can cause them eye strain. (Ideally the light bubbles would change to dark with a dark theme, but current AO3 css blocks the code needed for this.)
The Anatomy of the HTML
Wrap your whole chat block in a div with the 'chat' class:
<div class="chat">
...
</div>Each individual chat bubble has 3 components:
- The main wrapper
divwith the'bubble'class and either a'local'or'remote'class depending on which of your characters is talking.<div class="bubble local"> ... </div><div class="bubble remote"> ... </div> - The message of the chat bubble which is a
ptag with the'message'class on it.<p class="message"> ... </p> - And the hidden accessibility text to indicate who is talking. This is a
'span'element with the'ally'class, which goes inside the'message'element, and before the actual message text.
❗Important: Include a space between this'span'element and your message text to ensure the character's name and the first word of the message are not read out as a single word by screen readers. It also makes your code a little more readable. :)<span class="a11y">Your_Character_Name:</span>
Stack multiple messages within the outer 'chat' div, and you should end up with something like this:
<div class="chat">
<div class="bubble local"><p class="message"><span class="a11y">Ephyna:</span> Tell me a joke</p></div>
<div class="bubble remote"><p class="message"><span class="a11y">Bestie:</span> lol no pressure</p></div>
</div>✨Tip: Double check that all of the quote marks in your code are straight ones ' ' and not curly ones ‘ ’. Curly ones won't work!
The CSS for Your Workskin:
These CSS styles will work out of the box as long as you follow the HTML structure outlined above. They must be placed in a workskin; you can't paste them directly into your fic's chapter. Check out the AO3 FAQ for how to set up workskins if haven't made one before.
If you want to adjust the colors, the blue is set in .chat .local .message and .chat .local::after, and the grey in .chat .remote .message and .chat .remote::after. There are two hex codes for each that are repeated several times for the gradients. Make sure you don't forget the ::after colors — those are for the curly tail on the bubbles! :)
The fonts are set in the selectors .chat for remote and .chat .local for local messages.
If you do change the colors, make sure you test your work on both light and dark backgrounds!
.chat {
position: relative;
z-index: 1;
color: #111;
padding: 0 0.6rem;
max-width: 32rem;
overflow: hidden;
}
.chat .bubble {
position: relative;
display: block;
margin: .5rem 0;
max-width: 80%;
}
.chat .remote+.local,
.chat .local+.remote {
margin-top: .8em;
}
.chat .message {
border-radius: 1rem;
padding: .5rem 1rem;
margin: 0;
font-size: 0.85rem;
display: inline-block;
}
.chat .bubble::after {
content: "";
position: absolute;
z-index: -1;
display: block;
background-color: transparent;
width: 1.75rem;
height: 1.5rem;
bottom: -0.3rem;
}
.chat .local {
text-align: right;
color: #fff;
margin-left: auto;
}
.chat .local .message {
text-shadow: #1E36D1 0 0 0.75rem;
background: linear-gradient(-15deg, #1E36D1, #0C66F7);
box-shadow: inset -0.25rem -0.25rem 2rem -0.5rem #1E36D1,
inset 2.5rem 2rem 2.5rem -2.75rem #0C66F7;
}
.chat .local::after {
right: -1.75rem;
border-bottom-left-radius: 66%;
box-shadow: -1rem -0.1rem 0 -0.2rem #1E36D1;
}
.chat .remote {
text-align: left;
}
.chat .remote .message {
text-shadow: #D2D4D4 0 0 0.75rem;
background: linear-gradient(15deg, #D2D4D4, #F7F8F8);
box-shadow: inset 0.25rem -0.25rem 2rem -0.5rem #D2D4D4,
inset -2.5rem 2rem 2.5rem -2.75rem #F7F8F8;
}
.chat .remote::after {
left: -1.75rem;
border-bottom-right-radius: 66%;
box-shadow: 1rem -0.1rem 0 -0.2rem #D2D4D4;
}
.chat .a11y {
position: absolute;
clip: rect(1px, 1px, 1px, 1px);
overflow: hidden;
height: 1px;
width: 1px;
padding: 0;
border: 0;
}
