CSS Art in email
The concept of CSS art is about creating images out of hand written code rather than using any type of graphics editor. Some great examples can be found on css-art.com a.singeldiv.com and I’ve put together a CSS art collection on codepen. But I think my favourite examples can be found on diana-adrianne.com I strongly recommend checking out Diana’s work.
I love art. I love CSS. So it was only a matter of time before I had a go to see what I could achieve in email.
There have already been some great experiments created in email using a technique often called pixel art. This technique involves cutting an image up into blocks then placing it in a table and using background colours to create a blocky pixel like image for when images aren’t loaded. There is a great post on Litmus about email pixel art, and Mike Ragan a master of the technique did a great talk about pixel art in email back in 2015.
For me I wanted to create something more CSS based rather than table based but still have it work across email clients.
There are some practical uses but mostly this is just for fun.
*Just a quick note to say I’m going to completely ignore MSO Outlooks for now and tackle MSO Outlook support separately. So until we get to that section assume none of the following works in MSO versions of Outlook.*
Basic shapes
All of the artworks I’m going to cover are made up from variations of the following basic shapes.
Square
We just need a height
, width
to define the size and a background
so we can see it.
Circle
Here we’re just adding a border-radius
to make it into a circle. We have quite a few options here, we can set up to 8 values on a single element creating elliptical corners, with each of the 4 corners having a setting on each edge border-radius:0 50% 10px 5px / 5px 10px 15px 20%
.
Border radius has pretty good support across email clients a few that don’t support it are gmx
, wed.de
and older versions of IBM Notes. It’s also worth mentioning that Yahoo and AOL don’t support the /
separator (although we could use long hand styles there). So for this I’m limiting myself to only 4 values.
Triangle
We can use borders to create triangle shapes, I’ve got a more detailed write up on CSS triangle in email if you’re interested.
More advanced CSS
A lot of the web based CSS art uses more advanced things like CSS gradients, box-shadow
, transform
, postion
and clip-path
as well as ::before
and ::after
pseudo elements. These can really expand what is possible however email support isn’t quite there yet so I’m going to avoid them in this article, but if you’re only targeting certain email clients then feel free to experiment with those options some more.
Creating a picture
Everything we create is going to be using variations of those 3 simple shapes. The process I use it starting with a frame, then position one shape at time inside the until it creates a picture.
Frame
First we’re going to create a frame to hold the picture.
This serves several functions. It gives a height and width to the image, it adds alt text, it gives us a target to create scalable sizing, and defines an area for us to create our positioning from.
Positioning shapes in the frame
In web we’d use position:absolute
here but that doesn’t have great support in email, so instead we’re going to use a simplified version of the faux absolute position technique.
Inside the frame I’ve added <div style="max-height:0;max-width:0;"></div>
and placed a triangle inside it using a <u></u>
element. The max-height
and max-width
mean that this shape will take up no space inside the frame. I can then position it relative to the top left using margin-top
and margin-left
. I’m using a <u>
here to define the shape, purely to make the code easier to read. When looking at it I know <u>
will be a shape and <div>
will be a wrapper or position.
Now we have that working we can position a second triangle on top of it using the same positioning trick to create a 6 point start. Because both are set to use no height or width, they are both positioned from the same starting point.
Using negative space
To get a little more out of the limited resources available to us, we can use visual tricks like negative space to create the illusion of shapes, that are otherwise impossible with this technique. Above we’ve created a 6 point start but you designer may ask for a 5 point star so lets make the designer happy.
First we define a large triangle. <u style="border:1.75em solid transparent;border-bottom:4.5em solid gold;border-top:none;display:inline-block"></u>
then we overlay a smaller triangle that matches our background colour to create a cut out <u style="border:1.75em solid transparent;margin-top:3.5em;border-bottom:1em solid white;border-top:none;display:inline-block"></u>
Here I’ve changed the background of the frame so it’s easier to see the cut out.
Then we just add in 1 more triangle and we have a 5 point star using negative space.
There is a limitation here that we need to know the background colour but you could force that on the frame if you like.
Other visual tricks
There are a number of other tricks we can use, I’ll mention a few briefly to give you some ideas.
Crop - Place and shape inside another shape and use overflow:hidden
to crop it. This can be good for creating a shading affect.
Curved line - Use a board on one side of a circle that has no background colour.
Diagonal line - Place 2 long triangle on top of each other, one tall at the start going to a point at the end, that other starting at a point and expanding out.
MSO Outlook support
None of this will work in MSO Outlook. But we can use something else, Vector Markup Language (VML).
First up we hide what we’ve built from Outlook. Because this is built with simple elements all we need to to is add mso-hide:all
and it won’t show in MSO Outlook.
Then we replace the CSS image with a VML image. This is likely to just be ignored by other email clients, but if any extra spacing or content does show we can hide it with display:none;mso-hide:none;
.
I’m writing up more about how to create VML images in a separate post, which will be coming soon…
Creating more complex artwork
I wanted to see how far I can push this and try and create something impressive.
I found a picture of a Rickenbacker 4001 bass guitar online (I wanted to draw my own bass but I didn’t have a photo to hand when I started, so just grabbed a photo online). To help with the drawing I set the photo as a background image on the frame and slowly added shapes on top of it (269 shapes to be exact), it’s pretty much like tracing the image.
Practical uses
Ok so this is quite cool but can it be anything more than a gimmick?
It’s not time efficient. Most of the time it would be much quicker to create an image in a graphics editor.
It adds code weight directly to the HTML file. This could cause issues when trying to keep the HTML under 100kb.
So no, don’t change all of your images to be CSS based just yet, but there are some use cases where these are beneficial and would work well in production.
Images off email
Some users choose not to load images by default. So before they load the images, you could show a more interesting fallback rather than a blank space where an image was. Because of the time and effort it takes to make these it may be good to use more generic designs. For example, have a default graphic in place of a hero image or show a simple avatar in place of a profile picture.
Vector image
Essentially these are vector images, they can be scaled up infinitely without distorting and have better email client support than using <svg>
. As long as you’ve used em
to create the sizes, all you need to do is change the font-size
on the frame the image size changes without distorting. So if you want a large but simple image this would use minimal code and scale well.
Page breaks
You could you use something to transition between to different coloured sections of an email, or maybe spice up an <hr>
to make it a bit more fancy.
Dynamic content
You could create a graph using this technique and update the graphic automatically with the latest data when the email is sent.
Interactive images
You can add hover or click styles to allow the user to interact with an image.
Dark mode
Because this is all done in code you can easily change the colours in the images based on prefers-color-scheme
, or even change the image completely.