Tools
All you need to start an email template,
<!-- body.html -->{% extends "mailer/base.html" %} {% block content %}<h1>My header</h1><!-- Some email body -->{% endblock %}
This will import and use the email styles from base.html
Email clients suck. They all do. CSS is barely supported—even in clients like Gmail.
This kit was designed to be a simple and well supported on all email platforms.
You don't need to be a great writer, our messages just need to be useful and make sense.
Many of our emails fail this test. You can do it!
Email accounts are hacked all the time, don't put too many details in somebody's email inbox. Do not write sensitive personal or economic data in emails.
The design system is limited to only a few simple components in order to ensure compatibility across many different email clients. The system can be extended, but requires a really annoying amount of testing to validate that it works in all email clients. See below for the section on "Extending the email kit".
Don't even think about it.
In order to consistently apply margins and spacing, elements
The design system assumes you will be using a paragraph, table, list, button, or header to contain all text.
Do not write bare text in the body of the email. Use a paragraph tag. If you see red around the text in your email while previewing. This indicates bare text.
Do not nest margin elements. ~~<p><p></p></p>~~
Some emails sent form Carta do not use the design system and are rendered as plain text. These are not broken and are used for special cases.
The email design system uses a grid based on 8px.
This doesn't always work out, especially on mobile when sizes need to be reduced. Target using the 8px system.
Large space = 24px;
Small space = 16px;
I'm starting with buttons because they're complicated—It gets easier.
Due to compatibility issues buttons must used with the button.html
include.
Use {% include 'mailer/includes/button.html' ... %}
Example:
Buttons are the big blue action in most of our system emails.
In some email clients an anchor can't be styled to have padding or a background color. In order to provide action buttons to all clients the button must be included with the arguments of button_text
and button_url
.
Example:
{% render_as url %}{{ protocol }}://{{ current_site.domain }}{% url 'profiles:tasks' %}{{ my_url_variable }}{%end_render_as %} {% include 'mailer/includes/button.html' with **button_url=url** **button_text="View Requests**" %}
All of these accept strings of text or Django variables.
Name | Description |
---|---|
button_url | Button url is the complete formatted url to be used. This typically requires concatenation using the render_as Django tag. See below for usage of render_as |
button_text | The text to appear on the button. If the text of your email is dynamically generated in your template, use the render_as Django tag. |
class | To add an additional class to the button element, use the class argument. |
attributes | To add additional html attributes to the button anchor tag. The string is inserted inside the tag at render. |
Don't use ›
in buttons
That's the little angle right at the end of text links. The button is enough.
Use sentence case
Button text should be sentence case.
Place at the end of the section
If you have content after the button, place a <hr>
after the button.
Only one primary button
If you need multiple buttons, we'll need to add another class for secondary button styles. At the time of publication we have no emails with multiple buttons. We did in the past. Maybe you just structure a normal anchor for secondary actions?
render_as var
tagYou must import formatting tags to use: {% load formatting_tags %}
Due to how we use Django templates, we often need to import and use the render_as
tag to combine variables into strings.
This takes the content between the two tags {% render_as my_var %}
and {% end_render_as %}
and renders all contents to a string. Whitespace is stripped from the beginning and end of the content.
<!-- Document must have this line to use teh render_as tag-->{% load formatting_tags %}<!-- Assuming the variables:user_name = "Maxwell"company_name = "Carta"--><!-- Rendering a collection of html and variables to "my_var".-->{% render_as my_var %}This is {{ user_name }} from {{ company_name }}.{% end_render_as %}<!-- Use the variable by placing the name inside "{{ }}" -->{{ my_var }}<!-- Results-->This is Maxwell from Carta.
Header is 640x220
how you can use a different image:
Guilloche automatically changes
To enable confetti, add this snippet to the top of body.html
{% block show_confetti %}True{% endblock %}
Confetti is not currently supported in Outlook :(
Places the cobranded logo where the Carta logo typically is and moves the Carta logo to the top right.
To use a co-branded email provide an image url to a cobrand_logo
block at the top of body.html
.
WARNING: Image out of date. The current cobranded header no longer contains Carta branding.
{% block cobrand_logo %}{{ my_logo_url }}{% endblock %}
Not currently supported in Outlook. This is due to the logo image sizes not being consistent.
All emails must have a title
This is the large text at the top of an email.
Should be consistent with the email subject and fairly short.
Use <h1>
Reserved for email title only
.large
Use <h1 class="large">
Reserved for special occasions, such as a new grant.
Text must be very short, approximately 4 words or fewer.
Use <h2>
before the <h1>
A pre-heading to the title. This is optional flavor text.
Use the pre-title for excitement.
Don't overload it with content.
Don't use it as a subtitle.
Showing Large title with pre-title above.
Block level text container with a margin bottom.
<p>My text</p>
Reminder: Don't write text without a container element. All text must be contained within a semantic context and have a block element parent.
Don't put paragraphs inside of paragraphs.
Don't leave empty paragraphs.
I don't mean using the section element, that wouldn't actually work.
A line to divide sections.
Just use an <hr>
this is what html is for.
<!-- Just do this --><hr />
That HR dividing a page followed by an optional <h2>
header to start that section.
Tables are great, use them for everything!
.table-container
divA table must be wrapped in a <div class="table-container"></div>
This provides margin to the bottom of the table.
The container provides margin to the bottom of the table. Due to, (you guessed it!) an outlook bug, margins can't be appleid to tables.
.table-container
this provides margin to the bottom of the table..table-container
inside other elements.Display tabular data where the first cell of each column is the header to the row. Only provides two columns. For multiple columns, use a basic table.
Use a .key-pair-table
class to enable this layout.
<h3>My key pair title</h3><!-- Use H3 for table titles --><div class="table-container"><table class="key-pair-table"><tbody><tr><th>My key cell</th><!-- note the use of TH element --><td>My value</td></tr><tr><th>My key cell</th><td>My value</td></tr></tbody><tbody></tbody></table></div>
Use a key-pair-table when possible. Multiple column tables with headers don't render well in email or on small screens.
Display tabular data with multiple columns and headers on the top.
Use a .table
class on the table
element to enable this layout.
<h3>My table title</h3><!-- Use H3 for table titles --><div class="table-container"><table class="table"><thead><tr><th>Column one</th><th>Column two</th><th>Column three</th></tr></thead><tbody><tr><td>Cell one</td><td>Cell two</td><td>Cell three</td></tr><!-- add more TRs for more rows --></tbody><tbody></tbody></table></div>
Use <h3>
for table titles before the table container.
See The following grants were split in the example.
H4, and H5 are not allowed. H3 is slightly larger and allows for differentiation from table headers.
Content can be added immediately below the table before the margin. Useful for adding that fine point. The .table-footer
class adds a margin-top to the block. See 4 more items were signed or... in the example
<div class="table-container"><table class="table"><!-- My table contents --></table><div class="table-footer"><small class="lighten">*These values are all correct</small></div></div>
For some layouts a double height row is needed.
Removes border bottom form the row.
Used to graphically show progress. This is a hack made out of tables to be compatible with lesser email clients. Implementing dynamic visuals compatible with many clients is limited lower your expectations for achieving other graphs. This component offers only one bar.
In the vesting notification we show a progress bars to indicate vesting progresss.
<table class="progress-bar"><tbody><tr class="progress-bar--bar"><td class="progress-bar--progress" width="{{ percent_vested }}%">{{ percent_vested }}%</td><td></td></tr></tbody></table><table class="progress-label"><tbody><tr><td>Vesting start<br /><small class="lighten">{{ event.manager.start_date|date:"m/d/Y" }}</small></td><td class="last">Fully vested<br /><small class="lighten">{{ end_date|date:"m/d/Y" }}</small></td></tr></tbody></table>
Use <a>
for anchor elements.
Anchor elements are rendered in $color-blue
#1b98ee
.
The arrow at the end of a link
Do not use angle brackets or the greater than or less than sign.
Use ›
Use ›
HTML entity for links that stand alone such as learn more links at the end of a paragraph.
<a href="http://carta.horse/">Learn more ›</a>
Don't use it for mailto links nor links embedded in sentences.
<a href="mailto:mary@esharesinc.com">Contact support</a>
This is a "single right-pointing angle quotation mark". I call it a "Right Side Angle QUOte" as a way to remember it.
Avoid using images in your emails. The system is intended to be used without images, but exceptions can be made. Images are not reliable without extensive pre-formatting. Only use images with a known dimension where you can specify a height and width.
.entity-brand
class is used to place logo images in emails. Since they are inconsistent in background and scale: It adds a margin and border to offset it from the content of the email. Note: this should be disabled in outlook if exact sizes can't be provided.
<div class="entity-brand"><img src="dogs.jpeg" height="100" width="200" alt="It's dogs, okay!" /></div>
If you can't provide a height
and width
, you can't guarantee presentation in the email. In outlook the image will scale to the native dimensions of the image. If you don't know the aspect ratio of your image at the time of templating, there's no way to limit just one dimension without stretching the image. In outlook, if one dimension is provided, the other will default to 100px;
We removed decorated lists in this version. Decorative bullets and counters were not supported in many email clients.
⚠️ This section is out of date! The default list style is more condensed than as pictured. There is no spacing between list items in production. Use class "header-list" on the "ul" or "ol" element to add a space below each list item. This should only be used in the case where you are providing headers inside your list items.
use <ul>
<ul><li>My list item</li><li>Another list item</li><ul></ul></ul>
Use <ol>
<ol><li>List item one</li><li>List item two</li><ol></ol></ol>
Use <h4>
inside the <li>
If you would like an optional header for your list item, use an <h4>
to keep the font size the same as the list item counters/bullets.
<li class="header-list"><h4>Optional header</h4>This is where the rest of my conent goes. The H4 element is a block so it automatically pushes content to the nextline.</li>
Used to highlight block of text with. Provides a blue background to offset text from the body. Typically used when somebody "included a message"
<div class="messageblock"><h5>Message from the company</h5><!-- optional h5 --><!-- If: you want to preserve line breaks in your message -->{% autoescape off %} {{ message|safe|trim_whitespace|linebreaks_to_br }} {% endautoescape %}<!-- else: you don't want line breaks in your message -->{{ message|safe|trim_whitespace }}</div>
Yellow - monospace, and text center.
Only used for codes, do not use code block to decorate other content.
<div class="codeblock"><span class="codeblock--code">{{ code }}</span><span class="codeblock--caption">The code expires in 5 minutes.</span></div>
Not documented yet. This provides a gray background and monospace text. Use this only for internal error emails which contain tracebacks.
<strong>
for headers.32px, Medium, 40px line height
24px, Light, 36px line height
<hr>
.18px, Bold, 24px line height
16px, Bold, 24px line height
Screen | Type setting |
---|---|
Desktop | 16px, normal, 24px line height |
Mobile | 14px, normal, 21px line height |
Screen | Type setting |
---|---|
Desktop | 14px, normal, 21px line height |
Mobile | 12px, normal, 18px line height |
<small>
for bold .small
.small
class is applied to a paragraph element, the margin bottom is reduced to 12px
.<strong>
or .font-bold
<em>
For italics. .text-italic
$color-slate
#364453
<span class="darken">
or this is the default color..darken
class, this is the text color for all text in the content
section of the email.$color-gray-light-3
#686865
<span class="lighten">
for lighter text..lighten
class, this is the text color for all text in the footer
section of the email.$color-blue
#1b98ee
<a>
and you already knew that.→
Err on the side of not using centered text. For compatibility and consistency keep text left aligned.
Due to reduced legibility and the fact that you "LOOK LIKE YOUR SCREAMING", do not use all uppercase letters.
First of all, please don't. I know your PM is desperate for something to be bigger and red, but modifying emails is technically really hard. It's incredibly important to reduce the scope of what we allow as elements in the email kit to ensure stability.
If you modify the email kit you promise me you will test in all major email clients—including Outlook. Litmus.com in an amazing tool for testing.
Outlook is one of the most popular email clients in the world and is really common in law firms. We need to ensure our emails don't look broken for these users.
CSS and HTML are not rendered in the same way in Outlook. Microsoft chose to use Microsoft Word as the rendering engine for outlook. As you are aware, Word is not a web browser. Only basic html and css are supported. If you stick to the limited kit in this email it has been tested and is functional in outlook.
If you are desperate to implement something in Outlook, it uses a language called VML.
Show only in Outlook | |
---|---|
<!--[if mso]> | Start outlook-only code block |
<![endif]--> | End outlook-only code block |
Hide in Outlook | |
---|---|
<!--[if !mso]>--> | Start hide in outlook code block |
<!--<![endif]--> | End hide in outlook code block |
Many features of HTML and CSS do not work in many clients. These often have a workaround, but don't work as expected in many clients.
Plan on them not working in many clients. We use them for progressive enhancement, but Android mail clients generally don't support them.
Carta uses Django templating to make emails.
These files are required for your email.
body.html
subject.txt
samples.yml
The context is what python provides to the email template as variables. When being rendered the server passes these data to the template.
Variables are accessed
These lines typically appear at the top of your body.html. They are used to import extra features used to render your email. Don't add ones that you don't need.
{% load mailer %}
{% load formatting_tags %}
Include this extra formatting and filters, generally used for text manipulation. Such as pluralize
Adding static images bloats the carta-web git repo. Avoid adding new static images.
Blocks
Stylesheet include
As far as I can tell, magic does this step. But the css is parsed and applied as inline styles. or as a <style>
at the top of the document
media queries are in the style tag. This means they must be applied with !important
You can make them load locally, by making this change to
eshares/mailer/templatetags/mailer.py
Email validation shows up when viewing in the email preview to help enforce these standards. Email validation is done by way of CSS queries add a warning over invalid elements.
static/lib/eshares/css/email_validation.scss
Red text shadow indicates text that is not a child of an element—such as a paragraph. Ensure that email text is contained inside of a paragraph or other element for proper margins.
Is this page helpful?