Customizing Weavy

All components in the UIKit have a generic look and feel that adapts to most normal layouts, but if needed you can override and adjust their outer styling using CSS just like you would any regular HTML element.

<style>
  wy-messenger {
    flex: 1;
  }

  .my-custom-styles {
    margin: 1rem;
  }
</style>

<wy-messenger class="my-custom-styles" style="border: 1px solid red;">
</wy-messenger>

Custom properties

To control theme colors and general styling, Weavy components use CSS custom properties (also known as CSS variables). You can override them in your stylesheet with pure CSS — no preprocessor required.

To customize a property, simply override it in your stylesheet using a :root block. Here’s an example that changes the primary theme color.

:root {
  --wy-theme-color: red;
}

You can also target individual components or a subset of components with a specific class.

wy-messenger {
  --wy-theme-color: green;
}

wy-messenger.your-class {
  --wy-theme-color: blue;
}

Alternatively, you can set properties inline directly on an element.

<wy-messenger style="--wy-theme-color: blue"></wy-messenger>

CSS parts

Whereas custom properties offer a high-level way to customize Weavy, CSS parts offer a low-level way to customize individual components. Again, this is done with pure CSS — no preprocessor required.

Weavy components use a shadow DOM to encapsulate their styles and behaviors. As a result, you can’t simply target their internals with the usual CSS selectors. Instead, components expose “parts” that can be targeted with the CSS part selector, or ::part().

Here’s an example that hides the "New conversation" button in the messenger component.

wy-messenger::part(wy-conversation-new) {
  display: none;
}

Most (but not all) components expose parts. You can find them in each component’s documentation under the “CSS Parts” section.

Examples

Here are some examples of common customization options such as specifying a color theme and setting font properties etc.

Colors

The easiest way to quickly change the entire color theme is with the --wy-theme-color property. When specified, it automatically generates a complete color palette that applies to the specified components.

:root {
  --wy-theme-color: red;
}
wy-messenger {
  --wy-theme-color: #00ff00;
}
<wy-messenger style="--wy-theme-color: hsl(95deg, 38%, 62%);"></wy-messenger>

Another alternative is to add a <meta name="theme-color"> element to the <head of your page. When present, it is picked up by Weavy and used to generate a theme (meaning you don’t have to set the --wy-theme-color property as it is done automatically).

<head>
  ...
  <meta name="theme-color" content="#00ff00" />
</head>

If you want more precise control of the color theme you can define all color tones in the palette instead of setting the single --wy-theme-color property. The colors shades are named from 0 to 100, similar (but not equal) to lightness of the HSL color model, where 0 is dark and 100 is light.

We recommend generating colors tones using Material Theme Builder to get matching color tones and proper dark mode out of the box. This will usually meet Web color contrast standards to get minimum contrast ratio of 3:1.

Dark mode

Weavy has built in support for dark mode. The dark theme is based on the color tokens recommended for Material Design dark theme. That means it will follow WCAG recommendations and use your defined colors.

To enable dark mode for a component you just have to set the wy-dark class or set the --wy-color-scheme: dark; CSS custom property.

Example: Dark mode on all components

<html class="wy-dark">
  ...
  <body>
    ...
    <wy-messenger></wy-messenger>
  </body>
</html>

Example: Dark mode on a single component

<wy-messenger class="wy-dark"></wy-messenger>

Example: Dark mode using CSS variable

<style>
  :root {
    /* Set dark mode for all Weavy components */
    --wy-color-scheme: dark;

    /* Recommended: Set dark mode for the page and other components */
    color-scheme: dark;
  }
</style>
<wy-messenger></wy-messenger>

To get dark mode to follow the browser or system settings, you can toggle it using a media query script.

function setWeavyDarkMode(e) {
  if (e.matches) {
    document.documentElement.classList.add("wy-dark");
  } else {
    document.documentElement.classList.remove("wy-dark");
  }
}

const colorScheme = matchMedia("(prefers-color-scheme: dark)");

// Listen to dark mode changes
colorScheme.addEventListener("change", setWeavyDarkMode);

// Set initial dark mode
setWeavyDarkMode(colorScheme);

Typography

The font family used in components is normally automatically inherited from the page, but can customized by specifying a value for the --wy-font-family property.

:root {
  --wy-font-family: monospace;
}

Font sizes use rem units so they scale with the base font size, which is the font-size in the root (usually the <html> node). To override it you can set the --wy-font-size property.

:root {
  --wy-font-size: 1.5rem;
}

Sizing

The component sizing is by default based on 1rem root size on the page, typically 16px as default in the browser. You can override this sizing using --wy-size to set the base size unit for the components. Setting 2rem will double the scale of the components.

:root {
  --wy-size: 32px;
}

Borders and roundness

The border radius of corners can be set using --wy-border-radius. Note that this affects all rounded corners.

To specifically override the roundness of avatars it is also possible to set --wy-avatar-border-radius. You can also set --wy-border to specify the border width.

You can also set the outermost border radius on the components using --wy-border-radius-outer. This can be useful if you want to keep the roundness inside the components, but adapt the outer roundness to the container where you are placing it.

:root {
  --wy-border-radius-outer: 0;
  --wy-border-radius: 2px;
  --wy-border: 0.25rem;
}

Spacing

Spacing properties are used to provide consistent spacing between content in your app. All paddings and gaps are derived from these properties, but might be bigger or smaller depending on where in the components they are used.

You can adjust the outermost padding to fit your container properly using the --wy-padding-outer.

:root {
  --wy-padding-outer: 8px;
  --wy-padding: 1rem;
  --wy-gap: 12px;
}

Property reference

Weavy makes use of the following custom properties to provide a consistent appearance across components. Note that, because they live at the page level, they’re prefixed with --wy- to avoid collisions with other libraries.

:root {
  /* Theme colors */
  --wy-theme-color:               unset;
  --wy-color-scheme:              unset; /* normal | light | dark */

  /* Size */
  --wy-size:                      1rem; /* Base size for layout */
   
  /* Padding */
  --wy-padding:                   .5rem;
  --wy-padding-sm:                calc(.5  * var(--wy-padding, .5rem)); /* .25rem */
  --wy-padding-lg:                calc(1.5 * var(--wy-padding, .5rem)); /* .75rem */
  --wy-padding-outer:             var(--wy-padding, 0);
   
  /* Gap */
  --wy-gap:                       .5rem;
  --wy-gap-sm:                    calc(.5  * var(--wy-gap, .5rem)); /* .25rem */
  --wy-gap-lg:                    calc(1.5 * var(--wy-gap, .5rem)); /* .75rem */
  --wy-gap-xl:                    calc(2 * var(--wy-gap, .5rem)); /* 1rem */

  /* Border */
  --wy-border:                    1px;
  --wy-border-outline:            0;
  --wy-border-radius:             .5rem;
  --wy-border-radius-sm:          calc(var(--wy-border-radius, .5rem) - .25 * var(--wy-padding, .5rem)); /* .375rem */
  --wy-border-radius-lg:          var(--wy-border-radius, 1.25rem);
  --wy-border-radius-pill:        var(--wy-border-radius, 2.5rem);
  --wy-border-radius-outer:       var(--wy-border-radius, .5rem);
   
  /* Typography */
  --wy-font-family:               unset;
  --wy-font-monospace:            "ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace";
  --wy-font-size:                 var(--wy-size, 1em); /* Assumes the inherited font-size, typically 16px */

  --wy-font-weight:               unset;
  --wy-font-weight-bold:          600;

  --wy-line-height:               1.5;

  --wy-font-size-xxs:             calc(.625 * var(--wy-font-size, 1em)); /* .625em 10px */
  --wy-font-size-xs:              calc(.75  * var(--wy-font-size, 1em)); /* .75em 12px */
  --wy-font-size-sm:              calc(.875 * var(--wy-font-size, 1em)); /* .875em 14px */
  --wy-font-size-lg:              calc(1.125 * var(--wy-font-size, 1em)); /* 1.125em 18px */
  --wy-font-size-xl:              calc(1.25 * var(--wy-font-size, 1em)); /* 1.25em 20px */
  --wy-font-size-xxl:             calc(1.5 * var(--wy-font-size, 1em)); /* 1.5em 24px */

  --wy-headings-font-size:        var(--wy-font-size, 1em);
  --wy-headings-font-style:       unset;
  --wy-headings-font-family:      var(--wy-font-family, unset);
  --wy-headings-font-weight:      var(--wy-font-weight-bold, 600);
  --wy-headings-line-height:      var(--wy-line-height, 1.5);

  --wy-h1-font-size:              var(--wy-font-size-xxl, 1.5em);
  --wy-h1-font-weight:            var(--wy-headings-font-weight, var(--wy-font-weight-bold, 600));
  --wy-h1-margin:                 0 0 var(--wy-gap, .5rem);

  --wy-h2-font-size:              var(--wy-font-size-xl, 1.25em);
  --wy-h2-font-weight:            var(--wy-headings-font-weight, var(--wy-font-weight-bold, 600));
  --wy-h2-margin:                 var(--wy-gap-xl, calc(2 * var(--wy-gap, .5rem))) 0 var(--wy-gap-sm, calc(.5  * var(--wy-gap, .5rem)));

  --wy-h3-font-size:              var(--wy-font-size-lg, 1.125em);
  --wy-h3-font-weight:            var(--wy-headings-font-weight, var(--wy-font-weight-bold, 600));
  --wy-h3-margin:                 var(--wy-gap-xl, calc(2 * var(--wy-gap, .5rem))) 0 var(--wy-gap-sm, calc(.5  * var(--wy-gap, .5rem)));

  --wy-h4-font-size:              var(--wy-font-size, 1em);
  --wy-h4-font-weight:            var(--wy-headings-font-weight, var(--wy-font-weight-bold, 600));
  --wy-h4-margin:                 var(--wy-gap-xl, calc(2 * var(--wy-gap, .5rem))) 0 0;

  --wy-h5-font-size:              var(--wy-font-size, 1em);
  --wy-h5-font-weight:            var(--wy-headings-font-weight, var(--wy-font-weight-bold, 600));
  --wy-h5-margin:                 0;

  --wy-h6-font-size:              var(--wy-font-size, 1em);
  --wy-h6-font-weight:            inherit;
  --wy-h6-margin:                 0;

  /* Documents */
  --wy-document-headings-font-family: var(--wy-headings-font-family, var(--wy-font-family, unset));
  --wy-document-headings-line-height: var(--wy-headings-line-height, var(--wy-line-height, 1.5));

  --wy-document-h1-font-size:     calc(2 * var(--wy-font-size, 1em)); /* 2em 32px */
  --wy-document-h1-font-weight:   var(--wy-font-weight-bold, 600);
  --wy-document-h1-margin:        0 0 var(--wy-gap, .5rem);

  --wy-document-h2-font-size:     calc(1.5 * var(--wy-font-size, 1em)); /* 1.5em 24px */
  --wy-document-h2-font-weight:   var(--wy-font-weight-bold, 600);
  --wy-document-h2-margin:        var(--wy-gap-xl, calc(2 * var(--wy-gap, .5rem))) 0 var(--wy-gap-sm, calc(.5  * var(--wy-gap, .5rem)));

  --wy-document-h3-font-size:     calc(1.25 * var(--wy-font-size, 1em)); /* 1.25em 20px */
  --wy-document-h3-font-weight:   var(--wy-font-weight-bold, 600);
  --wy-document-h3-margin:        var(--wy-gap-xl, calc(2 * var(--wy-gap, .5rem))) 0 var(--wy-gap-sm, calc(.5  * var(--wy-gap, .5rem)));

  --wy-document-h4-font-size:     calc(1.125 * var(--wy-font-size, 1em)); /* 1.125em 18px */
  --wy-document-h4-font-weight:   var(--wy-font-weight-bold, 600);
  --wy-document-h4-margin:        var(--wy-gap-xl, calc(2 * var(--wy-gap, .5rem))) 0 0;

  --wy-document-h5-font-size:     var(--wy-font-size, 1em); /* 1em 16px */
  --wy-document-h5-font-weight:   var(--wy-font-weight-bold, 600);
  --wy-document-h5-margin:        var(--wy-gap-xl, calc(2 * var(--wy-gap, .5rem))) 0 0;

  --wy-document-h6-font-size:     var(--wy-font-size, 1em); /* 1em 16px */
  --wy-document-h6-font-weight:   var(--wy-font-weight-bold, 600);
  --wy-document-h6-margin:        0;

  /* Links */
  --wy-link-decoration:           none;
  --wy-link-hover-decoration:     var(--wy-link-decoration, none);

  /* Tables */
  --wy-table-cell-padding-x:      var(--wy-gap-sm, calc(.5  * var(--wy-gap, .5rem)));
  --wy-table-cell-padding-y:      var(--wy-gap-sm, calc(.5  * var(--wy-gap, .5rem)));

  /* Transitions */
  --wy-transition-reveal-delay:   1s;

  /* Opacity */
  --wy-opacity-backdrop:          95%;
  --wy-opacity-muted:             65%;
  --wy-opacity-disabled:          38%;

  /* State layer */
  --wy-opacity-state-hover:       8%;
  --wy-opacity-state-focus:       12%;
  --wy-opacity-state-active:      12%;
  --wy-opacity-state-drag:        16%;

  /* Components */
  --wy-titlebar-height:           calc(max(1lh, var(--wy-button-size, 2.5rem)) + 2 * var(--wy-padding-sm, .25rem)); /* 3rem */
  --wy-toolbar-height:            calc(max(1lh, var(--wy-button-size, 2.5rem)) + 2 * var(--wy-padding-sm, .25rem)); /* 3rem */
  --wy-footerbar-height:          4rem;

  /* Buttons */
  --wy-button-size:               calc(var(--wy-button-line-height, 1.5) * 1rem + 2 * var(--wy-button-padding-y, var(--wy-padding, .5rem))); /* 2.5rem */
  --wy-button-padding-x:          calc(var(--wy-padding, .5rem) + 2 * var(--wy-button-padding-y, var(--wy-padding, .5rem))); /* 1.5rem */
  --wy-button-padding-y:          var(--wy-padding, .5rem);
  --wy-button-gap:                var(--wy-gap-sm, calc(.5  * var(--wy-gap, .5rem)));
  --wy-button-font-family:        var(--wy-font-family, unset);
  --wy-button-font-size:          var(--wy-font-size, 1em);
  --wy-button-font-weight:        var(--wy-font-weight, unset);
  --wy-button-line-height:        var(--wy-line-height, 1.5);
  --wy-button-border-width:       var(--wy-border-outline, 0);
  --wy-button-border-color:       transparent;
  --wy-button-border-radius:      var(--wy-border-radius, 1.25rem);

  /* Inputs */
  --wy-input-padding-y:           var(--wy-padding, .5rem);
  --wy-input-padding-x:           var(--wy-padding-lg, calc(1.5 * var(--wy-padding, .5rem)));
  --wy-input-font-family:         var(--wy-font-family, inherit);
  --wy-input-font-size:           var(--wy-font-size, 1em);
  --wy-input-font-weight:         var(--wy-font-weight, unset);
  --wy-input-line-height:         calc(var(--wy-line-height, 1.5) * 1rem);
  --wy-input-border-width:        var(--wy-border, 1px);
  --wy-input-border-radius:       var(--wy-border-radius, .5rem);
  --wy-input-filled-border-radius:var(--wy-border-radius-lg, var(--wy-border-radius, 1.25rem));
  --wy-input-filled-border-width: var(--wy-border-outline, 0);
    
  /* Dropdowns */
  --wy-dropdown-padding-x:        var(--wy-padding-lg, calc(1.5 * var(--wy-padding, .5rem)));
  --wy-dropdown-padding-y:        var(--wy-padding, .5rem);
  --wy-dropdown-gap:              var(--wy-gap, .5rem);
  --wy-dropdown-border-radius:    var(--wy-border-radius, .5rem);
  --wy-dropdown-border-width:     var(--wy-border, 1px);

  /* Items */
  --wy-item-title-font-size:        var(--wy-font-size, 1em);
  --wy-item-title-font-weight:      var(--wy-font-weight, unset);
  --wy-item-title-font-weight-bold: var(--wy-font-weight-bold, 600);

  /* Avatars */
  --wy-avatar-font-size:          .382em; /* Golden section */
  --wy-avatar-font-weight:        var(--wy-font-weight-bold, unset);
  --wy-avatar-border-radius:      var(--wy-border-radius, 50%);

  /* Messages */
  --wy-message-padding:           var(--wy-padding-lg, calc(1.5 * var(--wy-padding, .5rem)));

  /* Max width for embeds and image attachments */
  --wy-embed-content-max-size:    48rem;
  --wy-image-max-size:            32rem;
}
Support

To access live chat with our developer success team you need a Weavy account.

Sign in or create a Weavy account