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 forenum
properties. When using this, thevalue
must match theenum
value. 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>