How to Reference CSS Stylesheets in Email HTML Through PHP

March 30, 2022
Written by
Matt Nikonorov
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by

How to reference CSS Stylesheets in Email HTML Through PHP

It is not possible to reference CSS stylesheets in HTML-based email, as you commonly would in a web-based application by using: <link rel="stylesheet" href="style.css">.

Depending on your emails, this might be quite problematic. Luckily, there’s a way to overcome this limitation, which you'll learn in this tutorial.

Prerequisites

To follow along with this article, you’ll need the following:

Using SendGrid with Composer

In order to use SendGrid to send emails in PHP, you’ll need to install the SendGrid PHP API Library. Do this by running the command below.

composer require sendgrid/sendgrid

Retrieving a SendGrid API Key and Valid Sender identity

You’ll need a SendGrid API key and a valid sender identity in order to send emails through PHP using SendGrid.

First, to retrieve your SendGrid API key:

  1. Log into your SendGrid account.
  2. From the left side menu, click on Settings, then on API Keys.
  3. Click the Create API Key button on the top-right of the page to create a new API key. A new screen will appear.
  4. Inside the API Key Name field, enter a name for your API key.
  5. In the API Key Permissions section, select either Full Access or Restricted Access. If you decide to restrict access, be sure that the key has access to the Mail Send option.
  6. Click the Create & View button. You will be presented with your SendGrid API key.
  7. Take note of the SendGrid API key you’ve been provided.

Create a verified sender identity

To do that, log in to your SendGrid account, then going to Settings in the navigation bar. When there, click Sender Authentication. Then, proceed with Single Sender Verification by selecting Get Started under Verify an Address.

SendGrid Sender Authentication

You will be taken to the Single Sender Verification page. Under Create your First Sender, click Create New Sender to load a form modal.

SendGrid Sender Management

Fill in all of the fields in the form modal and then click Create.

SendGrid - Single Sender Verification - Create New Sender

Form Fields:

  • From Name: This is a user-friendly name that is displayed to your recipient when they receive their email.
  • From Email Address: This the email address that sends the email. SendGrid sends a verification email to the address you enter in this field. If you do not receive it after a short time, please refer back to the Sender settings and confirm that the "From" email is a valid email address.
  • Reply To: If the recipient replies to the email, the reply will go to this email address.
  • Company Address, City, State, Zip Code, Country: Your business address.
  • Nickname: A label for your sender identity to help you identify it more quickly, later. This label is not visible to your recipients.

Check the inbox of the email address that you entered, and click the link in the email to complete verification of the Sender email address.

If, for any reason, you need to resend the verification email, click the action menu on the Single Sender Verification page, and select Resend Verification. SendGrid will deliver a new confirmation email to the address you are attempting to verify.

SendGrid - Single Sender Verification - Resend Verification

If you have an authenticated domain and your sender email address matches that domain exactly, your sender identity will be verified automatically.

You will now see a page confirming the verification of your address. Click Return to Single Sender Verification to add more addresses or make any changes to the address you just verified.

Sender Verified

Reference Inline stylesheets

Now that you have everything set up, the limitation of not being able to reference stylesheets through email HTML can be solved using the file_get_contents() function. This function gets the contents of files and stores them in a string.

Before I demonstrate how to reference large CSS stylesheets using this method, to see how referencing stylesheets in email HTML works, create a new PHP file, named index.php, and paste the code below into the file.

<?php

require 'vendor/autoload.php';

$email = new \SendGrid\Mail\Mail(); 
$email->setFrom("<<SENDER EMAIL ADDRESS>>", "Example User");
$email->setSubject("Email");
$email->addTo("<<RECEIVER EMAIL ADDRESS>>", "Example User");
$emailBody = <<<EOF
<html lang="en">
<head>
<style>
.big {
    font-size: 40px;
    color: green;
}

.small {
    font-size: 20px;
    color: purple;
}
</style>
<title>Reference CSS Stylesheets</title>
</head>
<body>
<p class='big'>This is big and green</p>
<p class='small'>This is small and purple</p>
</body>
</html>
EOF;
$email->addContent( "text/html", $emailBody); 
$sendgrid = new \SendGrid('<<SENDGRID API KEY>>);
try {
$response = $sendgrid->send($email);
print $response->statusCode() . "\n";
print_r($response->headers());
print $response->body() . "\n";
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}

Then, replace the placeholders, <<SENDER EMAIL ADDRESS>> and <<RECEIVER EMAIL ADDRESS>>, with the sender and receive email addresses, and <<SENDGRID API KEY>> with your SendGrid API key.

The script will send an email saying “This is big and green” and “This is small and purple” from your verified sender email to the email address you use for testing.

With the script complete, execute it by running the command below

php index.php

The email sent will look like the image below.

Delivered email, version 1.

Reference Local Stylesheets

To reference the CSS used in the example above through a stylesheet on the same server, first create a CSS file, called style.css. Then, open the file and paste the CSS, below, into the file.

.big {
    font-size: 40px;
    color: green;
}

.small {
    font-size: 20px;
    color: purple;
}

Next, use the file_get_contents() function in your PHP script by updating index.php to match the version below. The lines to update have been highlighted.


<?php
require 'vendor/autoload.php';

$email = new \SendGrid\Mail\Mail(); 
$email->setFrom("sample.sender@gmail.com", "Example User");
$email->setSubject("E main");
$email->addTo("sample.user@gmail.com", "Example User");
$content = file_get_contents("style.css");
$emailBody = <<<EOF
<html>
<head>
<style>
$content
</style>
</head>
<body>
<p class='big'>This is big and green</p>
<p class='small'>This is small and purple</p>
</body>
</html>
EOF;
$email->addContent("text/html", $emailBody); 
$sendgrid = new \SendGrid('your API Key');
try {
$response = $sendgrid->send($email);
print $response->statusCode() . "\n";
print_r($response->headers());
print $response->body() . "\n";
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}

As you can see, to use a CSS file in your email's HTML, you need to fetch its contents, store them in a string, and render it inside the <style> tag.

If you run the PHP script above, you should see that it has successfully sent an email containing the styled HTML, which you can see an example of below.

Delivered email, version 2.

This is great, but what about large stylesheets? You can implement this method with larger stylesheets as well. Here is the CSS that is going to be used in style.css for this example:

h1 {
    font-size: 35px;
    background: mediumseagreen;
    color: white;
    border-radius: 10px;
    margin: 1% 1% 1% 1%;
    text-align: center;
}

.cont {
    width: 90%;
    padding: 10px;
    border: 2px solid salmon;
    border-radius: 10px;
    background: navajowhite;
}

.info {
    font-size: 25px;
    background: royalblue;
    color: white;
    border-radius: 10px;
    margin: 1% 1% 1% 1%;
    padding: 2% 2% 2% 2%;
    margin-top: 5%;
    text-align: center; 
}

Here is how your PHP script should look like if you want to reference and use this CSS in an email:

<?php

​​require 'vendor/autoload.php';

$email = new \SendGrid\Mail\Mail(); 
$email->setFrom("sample.sender@gmail.com", "Example User");
$email->setSubject("E main");
$email->addTo("sample.user@gmail.com", "Example User");
$content = file_get_contents("style.css");
$emailBody = <<<EOF
<html>
<head>
<style>
$content
</style>
</head>
<body>
<div class='cont'>
<h1>Hi, Matt! Here's what's new...</h1>
<div class='info'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tellus mauris a diam maecenas. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. 
Ut placerat orci nulla pellentesque. Fermentum iaculis eu non diam phasellus vestibulum lorem sed. 
Quam id leo in vitae. Eu feugiat pretium nibh ipsum. Dui vivamus arcu felis bibendum ut tristique et egestas. Nisi porta lorem mollis aliquam ut porttitor leo a. 
Felis donec et odio pellentesque diam volutpat.

Auctor urna nunc id cursus metus aliquam. Tempor orci dapibus ultrices in iaculis nunc sed. Venenatis tellus in metus vulputate eu scelerisque. Consequat nisl vel pretium lectus quam id leo. 
Amet purus gravida quis blandit turpis cursus in hac. Ut venenatis tellus in metus. Augue eget arcu dictum varius. Placerat duis ultricies lacus sed turpis tincidunt id. Velit aliquet sagittis id consectetur purus ut faucibus. Pulvinar etiam non quam lacus. 
Tellus in hac habitasse platea dictumst vestibulum rhoncus est. Neque gravida in fermentum et. Urna porttitor rhoncus dolor purus non enim praesent. Amet justo donec enim diam vulputate. 
Enim praesent elementum facilisis leo vel. Non curabitur gravida arcu ac tortor dignissim convallis aenean et. Vel eros donec ac odio tempor orci dapibus.
</div>
</div>
</body>
</html>
EOF;

$email->addContent("text/html", $emailBody); 
$sendgrid = new \SendGrid('your API Key');
try {
$response = $sendgrid->send($email);
print $response->statusCode() . "\n";
print_r($response->headers());
print $response->body() . "\n";
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}

Once you execute the PHP script above, you should see that it has successfully emailed the styled HTML to the receiver's email address.

Delivered email, version 3.

Reference remote stylesheets

If your email’s HTML requires remote CSS other domains, you can use the same file_get_contents() function used earlier, by replacing the local CSS file with the remote one's URL,  like so:

file_get_contents("https://silly-shaw-96f0f7.netlify.app/ex1.css")

This external stylesheet contains the same CSS that was used in the previous example, so if you execute the PHP script again, but this time using “https://silly-shaw-96f0f7.netlify.app/ex1.css" instead of “style.css” inside the file_get_contents() function, you should see that it will email the same HTML with the same style:

Delivered email, version 4.

Reference icons

Icons are occasionally used in emails, depending on your audience and context. However, they are only supported by about 35% of email clients. So while the following approach won’t work in all browsers, to reference icons in email CSS we can use the same file_get_contents() function.

Here’s an example using Google Icons:

require 'vendor/autoload.php';
$email = new \SendGrid\Mail\Mail(); 
$email->setFrom("sample.sender@gmail.com", "Example User");
$email->setSubject("E main");
$email->addTo("sample.user@gmail.com", "Example User");
$content = file_get_contents("https://fonts.googleapis.com/icon?family=Material+Icons");
$emailBody = <<<EOF
<html>
<head>
<style>
$content
</style>
</head>
<body>

<h1>Icons</h1>

<i class='material-icons'>cloud</i>
<i class='material-icons'>favorite</i>
<i class='material-icons'>attachment</i>
<i class='material-icons'>computer</i>
<i class='material-icons'>traffic</i>

</body>
</html>
EOF;

$email->addContent("text/html", $emailBody); 
$sendgrid = new \SendGrid('your API Key');
try {
$response = $sendgrid->send($email);
print $response->statusCode() . "\n";
print_r($response->headers());
print $response->body() . "\n";
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}

The icons should look like the following image when emailed:

Example of rendering icons in an email

Reference fonts

Similar to icons, custom fonts are also only supported by about 35% of email clients. Nevertheless, if you want to use custom fonts in email HTML, you can use the same method along with some fallback fonts for the email clients that don’t support custom fonts, as in the following example:

require 'vendor/autoload.php';
$email = new \SendGrid\Mail\Mail(); 
$email->setFrom("sample.sender@gmail.com", "Example User");
$email->setSubject("E main");
$email->addTo("sample.user@gmail.com", "Example User");
$content = file_get_contents("https://fonts.googleapis.com/css?family=Hubballi&display=swap");
$emailBody = <<<EOF
<html>
<head>
<style>
$content
body { 
    font-family: Hubballi, Arial; 
}
</style>
</head>
<body>
<p>Custom fonts are pretty cool</p>
</body>
</html>
EOF;

$email->addContent("text/html", $emailBody); 
$sendgrid = new \SendGrid('your API Key');
try {
$response = $sendgrid->send($email);
print $response->statusCode() . "\n";
print_r($response->headers());
print $response->body() . "\n";
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}

Here’s how the above example’s text should look like when emailed to an email client that supports custom fonts:

Example 1 of rendering fonts in an email

And here’s how this example’s text should look like when emailed to an email client that doesn’t support custom fonts:

Example 2 of rendering fonts in an email

Conclusion

I hope that this article was helpful and gave you an easy way of referencing stylesheets for different purposes in email HTML, through PHP.

Matt Nikonorov is a developer from Kazakhstan with a passion for data science, data mining, and machine learning. He loves developing web and desktop applications to make the world more interesting. When he’s not developing, you can reach him via Twitter.

"Email icon" by Free PNGimg.com is licensed under CC BY-NC 4.0