Better Svelte Email provides several utility functions to simplify working with inline styles in email templates.
Import
import {
styleToString ,
pxToPt ,
withMargin ,
combineStyles
} from 'better-svelte-email/utils' ;
styleToString
Converts a style object to a CSS string with proper formatting.
Signature
function styleToString (
style : Record < string , string | number | undefined >
) : string
Parameters
style
Record<string, string | number | undefined>
required
Object containing CSS properties in camelCase or kebab-case format
Returns
CSS string with semicolon-separated properties
Behavior
Converts camelCase property names to kebab-case (e.g., backgroundColor → background-color)
Filters out undefined, null, and empty string values
Joins properties with semicolons
Example
import { styleToString } from 'better-svelte-email/utils' ;
const styles = {
backgroundColor: '#fff' ,
fontSize: '16px' ,
lineHeight: 1.5 ,
padding: undefined // This will be filtered out
};
const cssString = styleToString ( styles );
// Result: "background-color:#fff;font-size:16px;line-height:1.5"
pxToPt
Converts pixel values to point values for better email client compatibility.
Signature
function pxToPt ( px : string | number ) : string
Parameters
Pixel value as a number or string (e.g., 16 or "16px")
Returns
Point value as a string with “pt” suffix (e.g., “12pt”)
The conversion uses the formula: 1px = 0.75pt (rounded to nearest integer)
Example
import { pxToPt } from 'better-svelte-email/utils' ;
const fontSize = pxToPt ( 16 ); // "12pt"
const lineHeight = pxToPt ( "20" ); // "15pt"
const padding = pxToPt ( 24 ); // "18pt"
Points are often more reliable than pixels in older email clients like Outlook. This utility is used internally by the Button component for MSO-specific styles.
withMargin
Converts margin shorthand props to a style object with pixel values. This is commonly used in email components that accept margin props.
Signature
type Margin = {
m ?: string ; // All sides
mx ?: string ; // Horizontal (left + right)
my ?: string ; // Vertical (top + bottom)
mt ?: string ; // Top
mr ?: string ; // Right
mb ?: string ; // Bottom
ml ?: string ; // Left
};
function withMargin ( props : Margin ) : Record < string , string >
Parameters
Object with margin shorthand properties Margin for all sides (e.g., “16”)
Horizontal margin (left and right)
Vertical margin (top and bottom)
Returns
Style object with margin properties in pixels (e.g., { marginTop: "16px" })
Priority Order
More specific props override less specific ones:
Individual sides (mt, mr, mb, ml) have highest priority
Directional shorthands (mx, my) override m
Global m has lowest priority
Example
import { withMargin } from 'better-svelte-email/utils' ;
// Simple margin on all sides
const margin1 = withMargin ({ m: "16" });
// Result: { margin: "16px" }
// Horizontal and vertical margins
const margin2 = withMargin ({ mx: "20" , my: "10" });
// Result: { marginLeft: "20px", marginRight: "20px", marginTop: "10px", marginBottom: "10px" }
// Mixed with override
const margin3 = withMargin ({ m: "16" , mt: "24" });
// Result: { margin: "16px", marginTop: "24px" }
// Individual sides
const margin4 = withMargin ({ mt: "8" , mr: "16" , mb: "8" , ml: "16" });
// Result: { marginTop: "8px", marginRight: "16px", marginBottom: "8px", marginLeft: "16px" }
combineStyles
Merges multiple CSS style strings into a single string, handling duplicates and formatting.
Signature
function combineStyles ( ... styles : ( string | undefined | null )[]) : string
Parameters
styles
(string | undefined | null)[]
required
Variable number of CSS style strings to combine. undefined and null values are filtered out.
Returns
Combined CSS string with semicolon-separated properties
Behavior
Filters out falsy values (undefined, null, empty strings)
Splits each style string by semicolons
Trims whitespace from each declaration
Flattens and joins all declarations
Later declarations override earlier ones (if properties conflict)
Example
import { combineStyles } from 'better-svelte-email/utils' ;
const baseStyle = "color: #333; font-size: 14px" ;
const hoverStyle = "color: #000" ;
const additionalStyle = undefined ; // Will be filtered out
const combined = combineStyles ( baseStyle , hoverStyle , additionalStyle );
// Result: "color:#333;font-size:14px;color:#000"
This utility is commonly used in components to merge default styles with user-provided styles. The Renderer will handle conflicting properties during the inlining process.
Complete Example
Here’s how these utilities work together in a custom email component:
< script lang = "ts" >
import { styleToString , pxToPt , withMargin , combineStyles } from 'better-svelte-email/utils' ;
import type { HTMLAttributes } from 'svelte/elements' ;
type Props = {
m ?: string ;
mx ?: string ;
my ?: string ;
mt ?: string ;
mr ?: string ;
mb ?: string ;
ml ?: string ;
style ?: string ;
children ?: any ;
} & HTMLAttributes < HTMLDivElement >;
let {
m , mx , my , mt , mr , mb , ml ,
style ,
children ,
... restProps
} : Props = $ props ();
// Generate margin styles from props
const marginStyles = withMargin ({ m , mx , my , mt , mr , mb , ml });
// Base card styles
const baseStyles = styleToString ({
backgroundColor: '#ffffff' ,
borderRadius: '8px' ,
padding: '24px' ,
fontSize: '16px' ,
lineHeight: 1.5
});
// MSO-specific styles using points
const msoFontSize = pxToPt ( 16 ); // "12pt"
// Combine all styles
const finalStyles = combineStyles (
baseStyles ,
styleToString ( marginStyles ),
style
);
</ script >
< div { ... restProps } style = { finalStyles } >
<!--[if mso]>
<div style="font-size: {msoFontSize}">
<![endif]-->
{@ render children ?.()}
<!--[if mso]>
</div>
<![endif]-->
</ div >
Usage:
< script >
import CustomCard from './CustomCard.svelte' ;
</ script >
< CustomCard
mt = " 32 "
mx = " 16 "
style = "border: 1px solid #e5e7eb"
>
< h2 > Welcome! </ h2 >
< p > This card uses all the style utilities. </ p >
</ CustomCard >
Renderer API Learn about the Renderer class
Components Explore built-in email components