jockles.com

All the Fannish things I do.

Megaskin by Jockles

← Previous Chapter · Chapter Index · Next Chapter →

Chapter 15: Email CSS

Thanks to DemigodOfAgni and La_Temperanza, whose How to insert Gmail emails in your fic and How to Mimic Email Windows this module is built on. Copied and adapted from them: the Gmail layout, headers and Reply buttons, and the generic email window's title bar, header lines, scrolling body, attachments and button bar.

15.1 Chapter Contents

This chapter goes through the CSS for the emails in the last chapter: the Gmail thread with its tables, and the plain email window with its title bar, fields, attachments and buttons.

15.2 Getting the CSS

The Email CSS is here: jockles.com/fic/megaskin/css/email.css. It needs the core CSS too (jockles.com/fic/megaskin/css/core.css), so paste the core into your work skin first and this underneath it.

15.3 How the Module is Laid Out

Gmail first (everything starting .gm), then the email window (everything starting .mail), then Links, Scrolling, Dark theme and Auto theme. Both kinds of email sit inside a mob box, so they get the core's phone width and can use no-scroll.

15.4 The Gmail Card

#workskin .gm {
  background: #ffffff;
  color: #202124;
  border: 1px solid #dadce0;
  border-radius: 14px;
  font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

A white card with Gmail's pale grey edge and rounded corners. Roboto is Google's font - readers who don't have it get Helvetica or Arial instead.

15.5 Why Gmail Uses Tables

The top of a Gmail email has a lot going on in one row: a picture on the left, the name and address in the middle, the date on the right, then a "to me" line under the name. Floats can do it, but they fall apart easily when names are long. A table keeps everything in its own column whatever the text is, and AO3 handles tables reliably, so the headers are real <table>s.

#workskin .gm table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
  margin: 0;
}

#workskin .gm td {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  vertical-align: top;
}

AO3's own site skin gives tables borders, padding and its own colours, which would make the email look like a spreadsheet. These two rules wipe all of that, so the table is just an invisible grid. vertical-align: top lines every cell up along the top, so the date sits level with the name.

More about the reset

color: inherit and font: inherit make the cells take the email's colours and font, instead of whatever the reader's AO3 skin says tables should look like. Without them, a reader with a dark site skin could end up with light text on the white card.

15.6 The Subject Line

#workskin .gm .gm-title { padding: 0.8em 0.4em 0.4em 0.9em; font-size: 1.35em; line-height: 1.25; }

#workskin .gm .gm-label {
  display: inline-block;
  margin-left: 0.4em;
  padding: 0.1em 0.5em;
  border-radius: 4px;
  background: #e8eaed;
  color: #5f6368;
  font-size: 0.55em;
  vertical-align: middle;
}

#workskin .gm .gm-star {
  width: 38px;
  padding-top: 1em;
  text-align: center;
  color: #5f6368;
  font-size: 1.2em;
}
  • The subject is big, like it is in Gmail.
  • The label ("Inbox") is a small grey chip. It sits inside the title, so its 0.55em is a little over half of the already big title text, which brings it back down to a bit smaller than normal text. vertical-align: middle lines it up with the middle of the subject.
  • The star gets its own narrow column (38px) on the right.

15.7 One Email

#workskin .gm .gm-msg { padding: 0.7em 0.9em 0.6em 0.9em; border-top: 1px solid #e8eaed; }

#workskin .gm .gm-pfp-cell { width: 46px; }

Each email in the thread has a thin line above it. The picture column is 46px wide - the picture's 36px and a gap - and in the HTML it has rowspan="2", so it stretches down beside both the name row and the "to me" row.

#workskin .gm .gm-pfp {
  display: block;
  width: 36px;
  height: 36px;
  line-height: 36px;
  text-align: center;
  border-radius: 50%;
  background-color: #5f6368;
  background-size: cover;
  background-position: center;
  color: #ffffff;
  font-size: 0.85em;
  font-weight: bold;
}
  • A round picture. With no picture in it, it shows initials in white: line-height the same as the height, plus text-align: center, puts the letters in the middle.
  • colour1 to colour10 change the circle's colour. The colours are in the core, shared with every app (see The Ten Colours in the core CSS chapter).
  • You can put a pfp span inside instead of initials, for a picture or one of the profiles from the core.
#workskin .gm .gm-from { font-weight: bold; line-height: 1.3; padding-top: 1px; }

#workskin .gm .gm-address { font-weight: normal; color: #5f6368; font-size: 0.82em; }

#workskin .gm .gm-date {
  width: 1%;
  white-space: nowrap;
  padding-top: 3px;
  text-align: right;
  color: #5f6368;
  font-size: 0.75em;
  line-height: 1.3;
}

The name is bold and the address after it is smaller and grey. The date is the clever one:

  • width: 1% asks for a column almost no width at all, and white-space: nowrap stops the date from wrapping. Together they make the column exactly as wide as the date and no wider, so the name gets all the space that's left.
  • The little padding-top nudges the smaller date text down so it lines up with the name.
#workskin .gm .gm-to { color: #5f6368; font-size: 0.82em; line-height: 1.3; }

#workskin .gm .gm-tools {
  text-align: right;
  color: #5f6368;
  letter-spacing: 0.3em;
  white-space: nowrap;
}

#workskin .gm .gm-body { display: block; padding: 0.6em 0 0.4em 0; line-height: 1.5; }

#workskin .gm .gm-body p { margin: 0.5em 0; }

The "to me" line is small and grey. The icons under the date (gm-tools) are spaced out with letter-spacing and kept on one line. The message itself has taller lines and gaps between paragraphs, so it reads like an email rather than a chat.

15.8 The Reply Buttons

#workskin .gm .gm-footer { display: block; padding: 0.7em 0.9em 0.9em 0.9em; border-top: 1px solid #e8eaed; }

#workskin .gm table.gm-actions {
  border-collapse: separate;
  border-spacing: 0.4em 0;
  margin: 0 -0.4em;
  width: 100%;
}

#workskin .gm table.gm-actions td {
  border: 1px solid #dadce0;
  border-radius: 18px;
  padding: 0.55em 0.2em;
  text-align: center;
  color: #5f6368;
  font-size: 0.9em;
}

Reply, Reply all and Forward are another table, one cell each, so they share the width evenly and never wrap onto two lines.

  • border-collapse: separate undoes the reset above for this table only, so each cell keeps its own border, and border-radius: 18px rounds each one into a pill.
  • border-spacing: 0.4em 0 puts a gap between the pills side to side, but none above or below.
  • Border spacing also adds a gap at the outside edges, so the pills wouldn't line up with the email above. margin: 0 -0.4em pulls the table out by the same amount on both sides, which cancels it.

15.9 The Email Window

#workskin .mail {
  border: 1px solid #cfcfcf;
  background: #ffffff;
  color: #000000;
  font-family: Arial, Helvetica, sans-serif;
}

A plain square window with no rounded corners, so it looks like an old desktop email program rather than any particular app.

#workskin .mail .mail-titlebar {
  display: block;
  overflow: hidden;
  margin: 0;
  padding: 0.3em 0.7em;
  background: #404040;
  color: #ffffff;
  font-weight: bold;
  white-space: nowrap;
  text-overflow: ellipsis;
}

#workskin .mail .mail-titlebar span {
  float: right;
  margin-left: 0.8em;
  color: #cfcfcf;
  letter-spacing: 0.4em;
}
  • The title bar is dark grey and stays on one line. If the title is too long, text-overflow: ellipsis cuts it off with "..." instead of spilling out (it needs overflow: hidden and nowrap to work).
  • The window controls ("_ X") go in a span that floats to the right. That's why the span goes first in the HTML - a float only moves things that come after it, so it has to be before the title.
#workskin .mail .mail-field {
  display: block;
  margin: 0;
  padding: 0.3em 0.7em;
  border-bottom: 1px solid #e3e3e3;
  background: #ffffff;
  color: #000000;
}

#workskin .mail .mail-field b {
  display: inline-block;
  min-width: 4.2em;
  color: #666666;
  font-weight: bold;
}

Each From, To and Subject line is its own strip with a line under it. The label in bold is given a min-width, so "To:" takes up as much room as "Subject:" and everything after the labels lines up in a neat column.

#workskin .mail .mail-body p { margin: 0.6em 0; }

#workskin .mail .mail-signature {
  margin-top: 1.2em;
  padding-top: 0.5em;
  border-top: 1px solid #e3e3e3;
  color: #666666;
  font-size: 0.9em;
}

Paragraphs get their gaps back, and the signature gets a line above it and goes smaller and grey.

15.10 Attachments

#workskin .mail .mail-attachment {
  display: inline-block;
  margin: 0.15em 0.2em 0.15em 0;
  padding: 0.15em 0.5em;
  border: 1px solid #cfcfcf;
  border-radius: 3px;
  background: #ffffff;
  color: #0b57d0;
  text-decoration: underline;
}

#workskin .mail .mail-attachment::before { content: "\1F4CE"; margin-right: 0.3em; }

#workskin .mail .mail-attachment.doc::before { content: "\1F5BA"; }

#workskin .mail .mail-attachment.img::before { content: "\1F5BC"; }

Each attachment is a small box with a blue underlined name, so it looks clickable. The icon in front comes from the CSS, not the HTML: ::before adds an emoji before the name. \1F4CE is the code for the paperclip 📎, \1F5BA is a document 🖺 and \1F5BC is a framed picture 🖼. Adding doc or img to the class swaps the paperclip for the other two.

Using a different emoji

The megaskin uses the emoji's code with a \ in front, rather than the emoji itself, which keeps the CSS plain text. To find a code, search for the emoji on Emojipedia and look for "Codepoints" - it'll say something like U+1F4CE. Drop the "U+" and put \ in front.

The emoji will look different depending on the reader's device, because each phone and computer draws its own.

15.11 The Button Bar

#workskin .mail .mail-buttons {
  display: block;
  margin: 0;
  padding: 0.4em 0.7em;
  border-top: 1px solid #cfcfcf;
  background: #f5f5f5;
  color: #000000;
}

#workskin .mail .mail-buttons span { display: inline-block; margin-right: 0.9em; }

A light grey strip at the bottom, with a gap after each button.

15.12 Links

#workskin .gm .fake-link, #workskin .gm a:not(.tl) { color: #1a0dab; }

#workskin .mail .fake-link, #workskin .mail a:not(.tl) { color: #0b57d0; }

Gmail's links are Google's dark blue, and the email window uses a brighter blue to match the attachments.

15.13 Scrolling

#workskin .mail .mail-body {
  display: block;
  max-height: 480px;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0.5em 0.7em;
  background: #ffffff;
  color: #000000;
}

#workskin .gm {
  max-height: 700px;
  overflow-y: auto;
  overflow-x: hidden;
}
  • In the email window, only the message scrolls, once it's taller than 480px. The title bar, the fields and the buttons stay where they are, like a real window. (The body's padding and colours live here too, so this is the rule to change if you want more space round the message.)
  • A Gmail thread scrolls as a whole once it's taller than 700px, with the same thin grey scrollbar as the rest of the megaskin.
  • Adding no-scroll to the email's box switches the scrolling off for either kind.

15.14 Themes

The dark theme follows Gmail's own dark mode for both kinds of email: a dark grey card (#202124) with light text, darker lines and chips, grey small print and a lighter blue for links (#8ab4f8). The email window's title bar goes almost black. The auto theme is the same again inside @media (prefers-color-scheme: dark).

15.15 Taking Parts Out

If you only use one kind of email, you can delete the other:

  • Only Gmail: delete every rule starting #workskin .mail, including in Links, Scrolling and the dark and auto blocks.
  • Only the email window: delete every rule starting #workskin .gm, the same way.

Within Gmail, you can also take out the subject line (gm-title, gm-label and gm-star) or the reply buttons (gm-footer and gm-actions) if you never use them. In the email window, attachments (mail-attachment), the signature (mail-signature) and the buttons (mail-buttons) can all go on their own. Keep the table reset - every Gmail header needs it.

← Previous Chapter · Chapter Index · Next Chapter →