Work Text:
Hi there! Here’s the result of my getting distracted and spending the afternoon on something few people are going to use (but I had fun anyway!): a chat log template! I tried to make it simple and easy to use, and thanks to the magic of flexbox, it should scale easily to different devices and screen sizes. This is what it looks like:
You can view the HTML by clicking on the button below. The entire chat log is wrapped inside a <div> container with the class “chatlog”. Within this, there are a few separate <div> containers which each indicate when a new user types in the chat. So all of User A’s messages are contained in one, then all of User B’s, and if User A replies, those replies have their own container too. These containers each have the class message-container, which I hope is self-explanatory. They also each have another class, user-N: the number N should be attached to a specific user (so User A has class user-1, User B has class user-2, etc.), which is used for the purpose of colour-coding. At the very end of the CSS file there are a few lines that read:
#workskin .chatlog .user-1 .username {
color: #7d2f00;
}
#workskin .chatlog .user-2 .username {
color: #7717b3;
}
#workskin .chatlog .user-1 .username {
color: #455300;
}
These determine the colour of each user’s username.
Within any one of these containers there is a, <h2> element (note: the aria-label attribute is there for screen readers) and another <div> element, this one with the class message-content. You’ll notice looking at the CSS that both the .message-container and .message-content divs (plus one other one) have the property display: flex; – this means that they use a layout mode called flexbox; this is a very flexible CSS layout mode which is too complicated and too far outside the scope of this post to explain (here is a fantastic explanation); therefore, I’ll just say that the reason I’ve used it is to make the chat log work on all (well, most – there might be a few edge cases where it doesn’t work) screen sizes.1
Now, one final thing: this template (and the associated CSS) has been designed so that you can add or remove the part showing the time a message was sent (since it may not always be relevant). To do this, you simply replace the .message-container div with the .message-content:
<div class="message-container user-1">
<h2 class="username" aria-label="Username">username1</h2>
<div class="message-content">
<p class="datetime" aria-label="Time of message">16:54</p<>
<div class="text-container">
<p class="line">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>
->
<div class="message-container user-1">
<h2 class="username" aria-label="Username">username1</h2>
<div class="text-container">
<p class="line">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
View the HTML
As always anything enclosed <!--like this--> is a comment and will be ignored by AO3’s HTML editor.
<div class="chatlog">
<div class="message-container user-1">
<h2 class="username" aria-label="Username">username1</h2>
<div class="message-content">
<p class="datetime" aria-label="Time of message">16:54</p>
<div class="text-container">
<p class="line">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>
<div class="message-container user-2">
<h2 class="username" aria-label="Username">username2</h2>
<div class="message-content">
<p class="datetime" aria-label="Time of message">16:56</p>
<div class="text-container">
<p class="line">Proin ut felis velit.</p>
</div>
</div>
</div>
<div class="message-container user-3">
<h2 class="username" aria-label="Username">username3</h2>
<div class="message-content">
<p class="datetime" aria-label="Time of message">16:56</p>
<div class="text-container">
<p class="line">Duis risus diam, condimentum eget metus vitae, lacinia rhoncus ante.</p>
<p class="line">Duis congue lorem id elementum lobortis.</p>
</div>
</div>
<div class="message-content">
<p class="datetime" aria-label="Time of message">16:58</p>
<div class="text-container">
<p class="line">Duis risus diam, condimentum eget metus vitae, lacinia rhoncus ante.</p>
</div>
</div>
</div>
</div>
View the CSS
Anything enclosed /* like this */ is a comment and will be ignored by AO3’s CSS editor.
#workskin .chatlog {
border: 1.5px solid #AAA;
/* The -webkit prefix makes things work on Chrome, Safari, and some versions of Opera. The -moz prefix makes it work on Firefox. */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
/* Sets the chatlog container off from the text by 1em, and makes the browser centre it horizontally. */
margin: 1em auto;
padding: 1em;
/* The next two lines mean the chatlog will take up 90% of the width of the main text until its width hits 160px: after that, it stays constant. This is so that the text is always readable, even if you have to scroll to see it. */
min-width: 160px;
width: 90%;
}
#workskin .chatlog * {
/* Sets the text font. Feel free to change this. */
font-family: "Courier New", Courier, monospace;
/* Sets font size to be the same as the surrounding text. To make it smaller, use a number less than 1; to make it larger, use a number greater than 1. */
font-size: 1em;
/* Useful as a reset. */
margin: 0;
}
/* As I said above, explaining flexbox is outside the scope of this post, so from here on, I'll note the purpose of certain flex properties, but not how they work. */
#workskin .chatlog .message-container,
#workskin .chatlog .message-content,
#workskin .chatlog .text-container {
/* Select versions of Chrome, Safari, and Opera */
display: -webkit-flex;
}
#workskin .chatlog .message-container,
#workskin .chatlog .message-content,
#workskin .chatlog .text-container {
/* Firefox */
display: -moz-box;
}
#workskin .chatlog .message-container,
#workskin .chatlog .message-content,
#workskin .chatlog .text-container {
/* Internet Explorer */
display: -ms-flexbox;
}
#workskin .chatlog .message-container,
#workskin .chatlog .message-content,
#workskin .chatlog .text-container {
/* Everything else */
display: flex;
}
#workskin .chatlog .message-container {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
padding: 0.5em;
}
/* The following two blocks make the background of the messages alternate when a new user jumps in. Starts with odd numbers because the :nth-child selector uses 1-based indexing. -_- */
#workskin .chatlog .message-container:nth-child(2n-1) {
background: #EEE;
}
#workskin .chatlog .message-container:nth-child(2n) {
background: #FFF;
}
#workskin .chatlog .username {
/* As the element is not a block element by default, have to set display to block in order to set the height. */
display: block;
/* For a language read from right to left, change this line to "float: right;". */
float: left;
/* Makes username text slightly larger than message text. */
font-size: 1.05em;
/* Bolds usernames. */
font-weight: bold;
line-height: 1.8em;
min-height: 1.8em;
/* Next three lines mean that if the username is too long for the screen, it is hidden by ellipses. */
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
}
#workskin .chatlog .message-content {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
/* More flexbox! */
-webkit-box-align: center;
-webkit-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
/* Following few lines mean that the date and text of a message run horizontally in the same direction as the language (e.g. left to right for English, right to left for Arabic) until the container is too small, in which case they then run vertically. */
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-direction: row;
-moz-box-orient: horizontal;
-moz-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
min-height: 1.5em;
margin: 0.25em 0;
width: 100%;
}
#workskin .chatlog .message-content .datetime {
color: #585858;
/* Puts the time at the top of its container. */
-webkit-align-self: flex-start;
-ms-flex-item-align: start;
align-self: flex-start;
/* Next three lines set the time container at a constant width of 2.5em, even when the parent container widens. */
-webkit-flex-basis: 2.5em;
-ms-flex-preferred-size: 2.5em;
flex-basis: 2.5em;
-webkit-box-flex: 0;
-webkit-flex-grow: 0;
-moz-box-flex: 0;
-ms-flex-positive: 0;
flex-grow: 0;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
/* Text is slightly smaller than the message text. */
font-size: 0.8em;
height: 1.875em;
line-height: 1.6em;
margin-right: 0.5em;
/* Based on AO3 having the minimum width of the work container set to 42em. The upshot of this is that if the width of the time container is larger than 37em, then it moves to the same row as the message. */
max-width: 37em;
min-height: 1.5em;
text-decoration: underline;
}
#workskin .chatlog .text-container {
/* Next two lines mean that the message text will run vertically and not wrap. */
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
flex-grow: 1;
}
#workskin .chatlog .text-container .line {
/* Sets minimum height of the line. */
-webkit-flex-basis: 1.5em;
-ms-flex-preferred-size: 1.5em;
flex-basis: 1.5em;
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
-moz-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
-webkit-flex-shrink: 1;
-ms-flex-negative: 1;
flex-shrink: 1;
width: 100%;
}
/* Next three blocks set the colour of the usernames for each user. Feel free to change these to whatever you want. */
#workskin .chatlog .user-1 .username {
color: #E67D3E;
}
#workskin .chatlog .user-2 .username {
color: #A53EE6;
}#workskin .chatlog .user-3 .username {
color: #CBE63E;
}
I think that’s everything . . . to be honest, I’m a little tipsy while I’m writing this, so I’ll probably end up editing it. Please ask any questions in the comments!
Footnotes
BACKIn this note: cross-compatibility! The trouble with web development is that not all browsers support all properties equally; solving this problem so that your site works on as many browsers as possible is called cross-compatibility. There are ways to get around this by using what’s called vendor prefixes, which allow the property to work on different browsers, and by using older syntax for flexbox. (Many thanks to Autoprefixer – their github – without whom I would need to have done it all manually. :D) Anyway, that’s what all the -webkit- and -moz- and -o- stuff is about (also, the seemingly redundant blocks that are repeating the display value are there because of the way AO3’s HTML sanitiser works). Flexbox is supported on most modern browsers (it has been out since 2009, after all), but I’m not sure what the distribution of browser types is throughout AO3’s userbase, and since flexbox is so important here, I’ve probably gone a bit overkill.
