When using custom HTML in some platforms that HTML require converting CSS styles to inline styles for email templates and embedded widgets.
If you were going to be sending emails using HTML then e-mail clients can be very finicky about non-lime CSS - sometimes completly breaking normal CSS and other times doing crazy things with the alignment.
Live Example
I have created a website that will automatically do this for you when you paste the full HTML into the content box, it will automatically detect buttons and links and apply inline CSS to those objects, this can been used from here
You paste you HTML here then use the Convert button:
The Problem
Email clients and many embedded systems don't support external CSS files or <style>
tags. They only recognize inline styles. This means converting code like this:
<style>
a { color: blue; font-weight: bold; }
button { background: red; color: white; padding: 10px; }
</style>
<a href="#">My Link</a>
<button>My Button</button>
Into this:
<a href="#" style="color: blue; font-weight: bold;">My Link</a>
<button style="background: red; color: white; padding: 10px;">My Button</button>
I built a JavaScript tool that does three main things:
1. Parse the CSS
The script extracts CSS from <style>
tags and breaks it down into rules:
function parseCSS(cssText) {
const rules = {};
const ruleBlocks = cssText.split('}');
for (let block of ruleBlocks) {
// Extract selector and properties
const selector = block.substring(0, block.indexOf('{')).trim();
const declarations = block.substring(block.indexOf('{') + 1).trim();
// Parse individual CSS properties
const styles = {};
declarations.split(';').forEach(decl => {
const [property, value] = decl.split(':');
if (property && value) {
styles[property.trim()] = value.trim();
}
});
rules[selector] = styles;
}
return rules;
}
2. Match Elements to Styles
The tool finds all links and buttons, then determines which CSS rules apply to each element:
function getMatchingStyles(element, rules) {
const matchedStyles = {};
// Check tag name (a, button)
const tagName = element.tagName.toLowerCase();
if (rules[tagName]) {
Object.assign(matchedStyles, rules[tagName]);
}
// Check classes (.my-class)
if (element.className) {
element.className.split(' ').forEach(className => {
if (rules['.' + className.trim()]) {
Object.assign(matchedStyles, rules['.' + className.trim()]);
}
});
}
// Check ID (#my-id)
if (element.id && rules['#' + element.id]) {
Object.assign(matchedStyles, rules['#' + element.id]);
}
return matchedStyles;
}
3. Apply Styles Inline
Finally, it converts the matched styles into inline style attributes:
function convertToInline() {
// Extract CSS from <style> tags
const cssRules = parseCSS(extractedCSS);
// Find all links and buttons
const elements = document.querySelectorAll('a, button');
elements.forEach(element => {
const styles = getMatchingStyles(element, cssRules);
if (Object.keys(styles).length > 0) {
const styleString = Object.entries(styles)
.map(([prop, value]) => `${prop}: ${value}`)
.join('; ');
element.setAttribute('style', styleString);
}
});
}
Live Example
The tool includes a live preview so you can see exactly how your converted HTML will look. Here's what happens when you input this:
Input:
<style>
a { color: #007bff; text-decoration: none; font-weight: bold; }
button { background: #28a745; color: white; padding: 10px 20px; border: none; }
.special { color: red; }
</style>
<a href="#">Regular Link</a>
<a href="#" class="special">Special Link</a>
<button>My Button</button>
Output:
<a href="#" style="color: #007bff; text-decoration: none; font-weight: bold;">Regular Link</a>
<a href="#" class="special" style="color: red; text-decoration: none; font-weight: bold;">Special Link</a>
<button style="background: #28a745; color: white; padding: 10px 20px; border: none;">My Button</button>
Why Just Links and Buttons?
I focused on links and buttons because they're the most commonly styled interactive elements and the ones that cause the most problems in email clients. They're also the elements that users interact with most, so consistent styling is crucial.
Conclusion
The tool has saved me countless hours of manual CSS conversion and ensures consistent results every time. It's particularly useful for email marketing campaigns and embedded widgets where external CSS isn't supported.