Styling
Learn how to style your components.
You can style custom components in two ways:
- Define properties in the
<script>element and pass them in the<style>and/or<template>tags. - Define CSS in the
<style>element and set them in the<template>tag.
You can use JavaScript in the <script> tag, but not the <style> tag.
You can define properties in the <script> tag that you then pass to a <style> or <template> tag to style your content.
Properties allow you to thoroughly customize a component. Here we’ll add some text styling.
<script>
export const config = {
"label": "My paragraph",
};
export const props = Component.defineProps({
color: {
section: 'Text',
label: 'Color',
schema: Component.props.string().optional(),
type: 'color',
},
'font-size': {
section: 'Text',
label: 'Size',
schema: Component.props.number().default(16),
type: 'number',
min: 14,
max: 30,
},
'text-align': {
section: 'Text',
label: 'Align',
schema: Component.props.enum(['left', 'center', 'right']).optional(),
type: 'toggle',
options: [
{ label: 'Left', value: 'left', icon: 'format_align_left' },
{ label: 'Center', value: 'center', icon: 'format_align_center' },
{ label: 'Right', value: 'right', icon: 'format_align_right' },
],
}
});
const styleObject = {
color: props.color,
'font-size': props['font-size'] + 'px',
'text-align': props['text-align'],
'line-height': '150%',
};
</script>
<template>
<p #set:style="styleObject">
This is a paragraph
</p>
</template>
Begin by adding export const props = Component.defineProps({}).
Above, we added three properties: color, font-size and text-align. Each has a number of additional settings. These are all optional, but we recommend you set some of them to help improve the user experience in the visual editor.
section- This groups properties together in the main properties menu.label- This sets a more user friendly name for the property.schema- This defines the type of property, validation (e.g number, string, boolean, enum, etc), default value, and whether it's optional. For a deeper look at validation, check out the zod validation library which our validation is built on.type- This defines the UI control that will show in the properties menu. You must set this to manage it in the visual editor.min,max- used to set minimum and maximum values of a numberoptions- this is a way to set user-friendly labels forenumproperties. When using this, thevaluemust match theenumvalue. Also, the icons set here are from Google icons.
In the example above, we set the style of the paragraph tag: <p #set:style="styleObject">.
<style> tags support variables defined in your <script> tag. Pass them as CSS values with the set() function.
.button {
background: set(background); /* quotes are optional when using alpha chararacters */
color: set('color');
}
If the value you want to access is inside of an object or array, you can use dot notation.
<script>
const theme = { background: 'blue' }
<script>
<style>
.button {
background: set('theme.background');
}
</style>
In your template, you'd then pass the CSS variable:
<a style="button"></div>
Use <style> tags to define CSS for your component then reference them in your <template> tag.
You can use all the conditional directives (#if, #else-if, #else) to render CSS.
<style #if="variant === 'primary'">
.primary-button {
background: blue;
color: white;
}
</style>
<style #else>
.default-button {
background: white;
color: blue;
}
</style>
By default, we merge all <style> tags together to avoid bloat. You can change this with the #isolated> attribute.
For example, these two <style> tags will be merged:
Source:
<style>
.a {
background: blue;
}
</style>
<style>
.b {
background: red;
}
</style>
Output:
<style>
.a {
background: blue;
}
.b {
background: red;
}
</style>
Sometimes you need to guarantee that a particular <style> tag lives on its own and is not merged with other <style> tags. You can do so by adding the #isolated attribute.
You might want this when sending emails to Gmail. If the <style> element contains any invalid CSS, Gmail will strip the entire block. But if you wrap this CSS in a #isolated block, Gmail will not strip the rest of the CSS.
<style #isolated>
.a {
background: blue;
}
</style>
<style>
.b {
background: red;
}
</style>
You can also group styles together by assigning a value to the #isolated attribute. This can prevent people from receiving a half-styled email; when an email client removes a <style> block, it will also remove all styles with the same value. This practice can help reduce code bloat, too.
<style #isolated="outook-web">
[class~="a"] {
background: blue;
}
</style>
<style #isolated="outook-web">
[class~="outlook-hide"] {
display: none;
}
</style>
<style>
.b {
background: red;
}
</style>
<style #isolated="interactive">
input:checked ~ .c {
background: green;
}
</style>
Some clients, like Thunderbird, do not support @media queries, so to work around that, use our media attribute on an isolated style to set screen breaks. <style> tags with the same isolated attribute value (like #isolated="thunderbird") that also have identical media attributes will be combined; however, if the media attributes aren't identical, then the styles will apply to different break points.
<style media="(min-width:600px)" #isolated="thunderbird">
.moz-text-html .test{background:red;}
</style>
In the example above, we prefixed the class to specify the Thunderbird email client - .moz-text-html. You'll want to do the same for any other email clients you want to target.