Styling web components

All of the main components in the UIKit (chat, files, messenger, posts) have a default look and feel that should fit in most normal layouts, but if needed you can override and adjust their outer styling using plain CSS.

  wy-messenger {
    flex: 1;

  .my-custom-styles {
    margin: 1rem;

  style="border: 1px solid red;"

Elements that are nested inside the main components can be styled via CSS variables that you add to your stylesheet.

CSS variables

As mentioned above, you can adjust the color and appearance of the UIKit components using CSS custom properties (also known as CSS variables). The simplest way to define them is within a :root { } selector in your stylesheet but you may also define them directly on a component (or on any parent element).

:root {
  /* base theme color */
  --wy-theme-color: red;

wy-messenger {
  /* override inherited font */
  --wy-font-family: monospace;

The font is normally inherited from the container where Weavy is placed, but as seen above, you can easily customize it by specifying a value for the --wy-font-family property.

Color theme

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

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

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.

:root {
  /* Tones based on #00ff00 generated using Material Theme Builder */

  /* Primary color  */
  --wy-primary-99: #f7ffee;
  --wy-primary-95: #cbffb8;
  --wy-primary-90: #77ff61;
  --wy-primary-80: #02e600;
  --wy-primary-70: #03c700;
  --wy-primary-60: #03a800;
  --wy-primary-50: #038b00;
  --wy-primary-40: #026e00;
  --wy-primary-30: #015300;
  --wy-primary-20: #013a00;
  --wy-primary-10: #002200;

  /* neutral color */
  --wy-neutral-99: #fcfdf6;
  --wy-neutral-95: #f1f1eb;
  --wy-neutral-90: #e2e3dc;
  --wy-neutral-80: #c6c7c1;
  --wy-neutral-70: #abaca6;
  --wy-neutral-60: #90918c;
  --wy-neutral-50: #767872;
  --wy-neutral-40: #5d5f5a;
  --wy-neutral-30: #454743;
  --wy-neutral-20: #2f312d;
  --wy-neutral-10: #1a1c18;

  /* error color */
  --wy-error-99: #fffbff;
  --wy-error-95: #ffedea;
  --wy-error-90: #ffdad6;
  --wy-error-80: #ffb4ab;
  --wy-error-70: #ff897d;
  --wy-error-60: #ff5449;
  --wy-error-50: #de3730;
  --wy-error-40: #ba1a1a;
  --wy-error-30: #93000a;
  --wy-error-20: #690005;
  --wy-error-10: #410002;

Default values

These are the default values which you can override with your own preferences.

:root {
    /* Typography */
    --wy-font-family:               unset;
    --wy-font-weight:               unset;
    --wy-line-height:               1.5;
    --wy-font-size-base:            1rem;
    --wy-font-size-xxs:             calc(0.625 * var(--wy-font-size-base, 1rem));
    --wy-font-size-xs:              calc(0.75 * var(--wy-font-size-base, 1rem));
    --wy-font-size-sm:              calc(0.875 * var(--wy-font-size-base, 1rem));
    --wy-font-size-lg:              calc(1.25 * var(--wy-font-size-base, 1rem));
    --wy-headings-font-style:       unset;
    --wy-headings-font-family:      var(--wy-font-family, unset);
    --wy-headings-font-weight:      500;
    --wy-headings-line-height:      var(--wy-line-height, 1.5);

    /* Border */
    --wy-border-radius:             0.5rem;
    --wy-border-radius-sm:          calc(0.75 * var(--wy-border-radius, 0.5rem));
    --wy-border-radius-lg:          calc(1.5 * var(--wy-border-radius, 0.5rem));
    --wy-border-radius-xl:          calc(2 * var(--wy-border-radius, 0.5rem));
    --wy-border-radius-pill:        50rem;

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

    /* Tables */
    --wy-table-cell-padding-x:      .25rem;
    --wy-table-cell-padding-y:      .25rem;

    /* Inputs */
    --wy-input-padding-y:           .4375rem;
    --wy-input-padding-x:           .75rem;
    --wy-input-font-family:         var(--wy-font-family, inherit);
    --wy-input-font-size:           var(--wy-font-size-base, 1rem);
    --wy-input-font-weight:         var(--wy-font-weight, unset);
    --wy-input-line-height:         var(--wy-line-height, 1.5rem);
    --wy-input-border-width:        1px;
    --wy-input-border-radius:       var(--wy-border-radius, .5rem);

    /* Shadows */
    --wy-shadow-level0:             none;
    --wy-shadow-level1:             0 0.125rem 0.125rem 0 rgba(0, 0, 0, 0.14), 0 0.1875rem 0.0625rem -0.125rem rgba(0, 0, 0, 0.2), 0 0.0625rem 0.3125rem 0 rgba(0, 0, 0, 0.12);
    --wy-shadow-level2:             0 0.25rem 0.3125rem 0 rgba(0, 0, 0, 0.14), 0 0.0625rem 0.625rem 0 rgba(0, 0, 0, 0.12), 0 0.125rem 0.25rem -0.0625rem rgba(0, 0, 0, 0.2);
    --wy-shadow-level3:             0 0.5rem 0.625rem 0.0625rem rgba(0, 0, 0, 0.14), 0 0.1875rem 1.25rem 0.125rem rgba(0, 0, 0, 0.12), 0 0.3125rem 0.3125rem -0.1875rem rgba(0, 0, 0, 0.2);
    --wy-shadow-level4:             0 1rem 2.25rem 0.125rem rgba(0, 0, 0, 0.14), 0 0.375rem 1.875rem 0.3125rem rgba(0, 0, 0, 0.12), 0 0.5rem 0.625rem -0.3125rem rgba(0, 0, 0, 0.2);

    /* Transitions */
    --wy-transition-curve:          cubic-bezier(0.4, 0, 0.2, 1);
    --wy-transition-duration:       0.2s;
    --wy-transition-duration-fast:  0.1s;
    --wy-transition:                var(--wy-transition-duration, 0.2s) var(--wy-transition-curve, cubic-bezier(0.4, 0, 0.2, 1));
    --wy-transition-fast:           var(--wy-transition-duration-fast, 0.1s) var(--wy-transition-curve, cubic-bezier(0.4, 0, 0.2, 1));

    /* 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:             3rem;
    --wy-footerbar-height:          4rem;

    /* Buttons */
    --wy-btn-padding-x:             1.5rem;
    --wy-btn-padding-y:             .5rem;
    --wy-btn-font-family:           var(--wy-font-family, unset);
    --wy-btn-font-size:             var(--wy-font-size-base, 1rem);
    --wy-btn-font-weight:           400;
    --wy-btn-line-height:           var(--wy-line-height, 1.5);
    --wy-btn-border-width:          0;
    --wy-btn-border-color:          transparent;
    --wy-btn-border-radius:         1.25rem;

    /* Avatars */
    --wy-avatar-font-size:          .382em;
    --wy-avatar-font-weight:        600;

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. You can also apply it to parent node to enable dark theme for multiple components.

Example: Dark mode on a single component

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

Example: Global dark mode

<html class="wy-dark">

Automatic dark mode

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) {
  } else {

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

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

// Set initial dark mode
Weavy Docs