Styling web components

All of the main components in the UIKit (chat, comments, 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.

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

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

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

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.

Sizing

Components can scale the size of both the font and the UI. Both are based on the same measurement and is typically defaulted to 16px by the browser if nothing else is specified.

Scaling the font

The font-size is normally inherited from the container where the component is placed. You can also define the font-size for all components or individual components using the --wy-font-size property. This scales only the font and not the UI.

:root {
  /* Base font size */
  --wy-font-size: 2rem;
}

wy-messenger {
  /* Individual font size */
  --wy-font-size: 1.5rem;
}

wy-chat {
  /* Regular individual font size. Note: this is overridden by any --wy-font-size */
  font-size: 12px;
}

Scaling the UI

Weavy scales the UI based on rem, which is the font-size in the root (usually the <html> node). The rem is typically set by the browser to 16px. You can set the rem for all components or individual components using the --wy-rem property.

:root {
  /* Base UI size (2x) */
  --wy-rem: 2rem;
}

wy-messenger {
  /* Individual UI size (1.5x) */
  --wy-rem: 24px;
}

Scaling both font and UI

To scale both the UI and the font proportionally together just set both --wy-rem and --wy-font-size to the same value.

:root {
  /* Base scaling of both font and UI */
  --wy-rem: 2rem;
  --wy-font-size: var(--wy-rem);
}

Read about sizing using ems and rems on MDN

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

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

: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 {
  /* Base size for layout*/
  --wy-rem:                       1rem;

  /* Typography */
  --wy-font-family:               unset;
  --wy-font-weight:               unset; 
  --wy-font-size:                 1em; /* Assumes the inherited font-size, typically 16px */

  --wy-line-height:               1.5;

  --wy-font-size-base:            var(--wy-font-size, 1em); /* Deprecated, use --wy-font-size instead */

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

  --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:             calc(0.5  * var(--wy-rem, 1rem)); /* .5rem */
  --wy-border-radius-sm:          calc(0.75 * var(--wy-border-radius, calc(0.5 * var(--wy-rem, 1rem)))); /* .375rem */
  --wy-border-radius-lg:          calc(1.5  * var(--wy-border-radius, calc(0.5 * var(--wy-rem, 1rem)))); /* .75rem */
  --wy-border-radius-xl:          calc(2    * var(--wy-border-radius, calc(0.5 * var(--wy-rem, 1rem)))); /*  1rem */
  --wy-border-radius-pill:        calc(50   * var(--wy-rem, 1rem)); /* 50rem */

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

  /* Tables */
  --wy-table-cell-padding-x:      calc(0.25 * var(--wy-rem, 1rem));
  --wy-table-cell-padding-y:      calc(0.25 * var(--wy-rem, 1rem));

  /* Inputs */
  --wy-input-padding-y:           calc(0.4375 * var(--wy-rem, 1rem));
  --wy-input-padding-x:           calc(0.75 * var(--wy-rem, 1rem));
  --wy-input-font-family:         var(--wy-font-family, inherit);
  --wy-input-font-size:           var(--wy-font-size-base, 1em);
  --wy-input-font-weight:         var(--wy-font-weight, unset);
  --wy-input-line-height:         var(--wy-line-height, calc(1.5 * var(--wy-rem, 1rem)));
  --wy-input-border-width:        1px;
  --wy-input-border-radius:       var(--wy-border-radius, calc(0.5 * var(--wy-rem, 1rem)));

  /* 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:             calc(3 * var(--wy-rem, 1rem));
  --wy-footerbar-height:          calc(4 * var(--wy-rem, 1rem));

  /* Buttons */
  --wy-btn-padding-x:             1.5em;
  --wy-btn-padding-y:             0.5em;
  --wy-btn-font-family:           var(--wy-font-family, unset);
  --wy-btn-font-size:             var(--wy-font-size-base, 1em);
  --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.25em;

  --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">
  ...
  <body>
    ...
    <wy-messenger></wy-messenger>
  </body>
</html>

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) {
    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);