Styling

Learn how to style your components.

You can style custom components in two ways:

  1. Define properties in the <script> element and pass them in the <style> and/or <template> tags.
  2. 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.

Style using JavaScript

You can define properties in the <script> tag that you then pass to a <style> or <template> tag to style your content.

Define properties

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 number
  • options - this is a way to set user-friendly labels for enum properties. When using this, the value must match the enum value. Also, the icons set here are from Google icons.

Pass properties into the <template> tag

In the example above, we set the style of the paragraph tag: <p #set:style="styleObject">.

Pass properties into the <style> tag

<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>

Style using CSS

Use <style> tags to define CSS for your component then reference them in your <template> tag.

Conditional CSS

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>

Multiple <style> tags

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>

Standalone styles

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>