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.

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>

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

Borders

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.

:root {
  --wy-border-radius: 2px;
  --wy-border: .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.

:root {
  --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;

  /* Size */
  --wy-size:                        1rem;
   
  /* Padding */
  --wy-padding:                     .5rem;
  --wy-padding-sm:                  calc(.5  * var(--wy-padding, .5rem));
  --wy-padding-lg:                  calc(1.5 * var(--wy-padding, .5rem));
   
  /* Gap */
  --wy-gap:                         .5rem;
  --wy-gap-sm:                      calc(.5  * var(--wy-gap, .5rem));
  --wy-gap-lg:                      calc(1.5 * var(--wy-gap, .5rem));

  /* 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));
  --wy-border-radius-pill:          var(--wy-border-radius, 2.5rem);
   
  /* Typography */
  --wy-font-family:                 unset;
  --wy-font-size:                   var(--wy-size, 1em);

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

  --wy-line-height:                 1.5;

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

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

  /* Links */
  --wy-link-decoration:             none;
  --wy-link-hover-decoration:       unset;

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

  /* Opacity */
  --wy-opacity-backdrop:            95%;
  --wy-opacity-muted:               38%;
  --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%;

  /* Surface elevation */
  --wy-surface-1-mix:               5%;
  --wy-surface-2-mix:               8%;
  --wy-surface-3-mix:               11%;
  --wy-surface-4-mix:               12%;
  --wy-surface-5-mix:               14%;

  /* Components */
  --wy-appbar-height:               calc(max(1lh, var(--wy-button-size, 2.5rem)) + 2 * var(--wy-padding, .25rem));
  --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))); 
  --wy-button-padding-x:            calc(var(--wy-padding, .5rem) + 2 * var(--wy-button-padding-y, var(--wy-padding, .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, 2.5rem);

  /* 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:           var(--wy-line-height, 1.5rem);
  --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-pill, var(--wy-border-radius, 2.5rem));
  --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);

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

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

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

Sign in or create a Weavy account