Skip to content

Theming Guide

AS Community widgets are styled using CSS custom properties (design tokens) inside a Shadow DOM. This guide explains how to apply tenant-specific themes correctly.

How Shadow DOM Affects Styling

All asc-* components render inside a Shadow DOM. This means:

  • Light-DOM stylesheets (i.e., a <style> block on the host page) cannot style elements inside the shadow root.
  • CSS custom properties do pierce the shadow boundary — they are inherited by shadow DOM children.

❌ What does NOT work

html
<!-- These styles cannot reach inside the shadow root -->
<style>
  asc-comment-widget .c-comment-widget {
    background: red;
  }
</style>

✅ What DOES work

CSS custom properties set on the host element are visible inside the shadow root:

html
<style>
  asc-comment-widget {
    --asc-color-interactive: #e30613;
  }
</style>

But the recommended approach is to use the theme-url attribute or tenantConfig.theme — both inject overrides via adoptedStyleSheets (see below).

Point the widget at a theme.overrides.json file:

html
<asc-comment-widget
  article-id="my-article"
  tenant-id="my-tenant"
  api-base-url="https://api.example.com"
  theme-url="/themes/my-tenant.json"
>
</asc-comment-widget>

The JSON file is a flat map of CSS custom property names to values:

json
{
  "--asc-color-interactive": "#e30613",
  "--asc-color-interactive-hover": "#b0040e",
  "--asc-color-brand-600": "#e30613",
  "--asc-font-family-body": "'Arial', sans-serif"
}

Alternative: tenantConfig.theme

If you're already loading the full tenant config, include theme directly:

js
const widget = document.querySelector('asc-comment-widget');
widget.tenantConfig = {
  id: 'welt',
  api: { baseUrl: 'https://api.welt.de', tenantId: 'welt' },
  branding: { displayName: 'WELT' },
  theme: {
    '--asc-color-interactive': '#e30613',
    '--asc-color-brand-600': '#e30613',
  },
};

How adoptedStyleSheets Works Internally

When a theme is applied (via theme-url or tenantConfig.theme), the widget:

  1. Creates a CSSStyleSheet with :host { --var: value; ... } rules.
  2. Appends it to shadowRoot.adoptedStyleSheets after Lit's static styles.

Because later entries in adoptedStyleSheets win in cascade order, tenant overrides always take priority over component defaults — without touching any style attribute on the host element.

shadowRoot.adoptedStyleSheets = [
  ...litStaticStyles,   // component defaults
  tenantThemeSheet,     // tenant overrides — wins
]

Semantic Token Reference

These are the tokens to override for visual customization. All defaults reference base scale tokens.

Text Colors

TokenDefault
--asc-color-text-primaryvar(--asc-color-neutral-900)
--asc-color-text-secondaryvar(--asc-color-neutral-600)
--asc-color-text-tertiaryvar(--asc-color-neutral-400)
--asc-color-text-disabledvar(--asc-color-neutral-300)
--asc-color-text-inversevar(--asc-color-neutral-0)
--asc-color-text-linkvar(--asc-color-brand-600)
--asc-color-text-link-hovervar(--asc-color-brand-800)

Background Colors

TokenDefault
--asc-color-bg-surfacevar(--asc-color-neutral-0)
--asc-color-bg-subtlevar(--asc-color-neutral-50)
--asc-color-bg-mutedvar(--asc-color-neutral-100)
--asc-color-bg-overlayvar(--asc-color-neutral-200)

Interactive (Buttons, Vote Controls, Focus)

TokenDefault
--asc-color-interactivevar(--asc-color-brand-600)
--asc-color-interactive-hovervar(--asc-color-brand-700)
--asc-color-interactive-activevar(--asc-color-brand-800)
--asc-color-interactive-subtlevar(--asc-color-brand-50)

Borders

TokenDefault
--asc-color-bordervar(--asc-color-neutral-200)
--asc-color-border-strongvar(--asc-color-neutral-400)
--asc-color-border-focusvar(--asc-color-brand-500)

Status

TokenDefault
--asc-color-status-errorvar(--asc-color-error)
--asc-color-status-error-bgvar(--asc-color-error-light)
--asc-color-status-warningvar(--asc-color-warning)
--asc-color-status-warning-bgvar(--asc-color-warning-light)
--asc-color-status-successvar(--asc-color-success)
--asc-color-status-success-bgvar(--asc-color-success-light)

Typography

TokenDefault
--asc-font-family-bodyvar(--asc-font-family-sans)
--asc-font-family-headingvar(--asc-font-family-sans)

Spacing & Shape

TokenDefault
--asc-component-padding-smvar(--asc-spacing-2) var(--asc-spacing-3)
--asc-component-padding-mdvar(--asc-spacing-3) var(--asc-spacing-4)
--asc-component-padding-lgvar(--asc-spacing-4) var(--asc-spacing-6)
--asc-component-radiusvar(--asc-border-radius-md)
--asc-focus-ring0 0 0 2px var(--asc-color-border-focus)

Base Token Overrides

You can also override base scale tokens directly. Common overrides:

json
{
  "--asc-color-brand-600": "#e30613",
  "--asc-color-brand-700": "#b0040e",
  "--asc-color-brand-50": "#fff0f0",
  "--asc-font-family-sans": "'Helvetica Neue', Arial, sans-serif"
}

Base tokens are: neutral scale (--asc-color-neutral-*), brand scale (--asc-color-brand-*), status colors, spacing (--asc-spacing-*), border radius, font families, font sizes, font weights, line heights, shadows, transitions.

theme.overrides.json Format

The file served at theme-url must be valid JSON — a flat object where every key starts with --:

json
{
  "--asc-color-interactive": "#e30613",
  "--asc-color-interactive-hover": "#b0040e",
  "--asc-color-brand-600": "#e30613",
  "--asc-font-family-body": "'Arial', sans-serif",
  "--asc-component-radius": "0"
}

Keys not starting with -- are silently ignored.


Component-Level CSS Variables

In addition to semantic tokens, each component exposes its own --asc-c-[component]-* variables. These let you fine-tune a single component without changing the global semantic tokens.

Set them the same way as semantic tokens — in your theme.overrides.json or tenantConfig.theme:

json
{
  "--asc-c-comment-form-submit-bg": "#e30613",
  "--asc-c-comment-widget-max-width": "60rem"
}

asc-comment-widget

VariableFallbackDescription
--asc-c-comment-widget-title-colorvar(--asc-color-text-primary)Widget title text color
--asc-c-comment-widget-title-font-sizevar(--asc-font-size-lg)Widget title font size
--asc-c-comment-widget-title-font-weightvar(--asc-font-weight-semibold)Widget title font weight
--asc-c-comment-widget-sort-btn-colorvar(--asc-color-text-secondary)Sort button text color
--asc-c-comment-widget-sort-btn-active-colorvar(--asc-color-text-primary)Active sort button text color
--asc-c-comment-widget-sort-btn-active-bgvar(--asc-color-bg-muted)Active sort button background
--asc-c-comment-widget-sort-btn-active-border-colorvar(--asc-color-border)Active sort button border color
--asc-c-comment-widget-max-width48remMax width of the widget container

asc-comment-item

VariableFallbackDescription
--asc-c-comment-item-author-colorvar(--asc-color-text-primary)Author display name color
--asc-c-comment-item-content-colorvar(--asc-color-text-primary)Comment body text color
--asc-c-comment-item-content-deleted-colorvar(--asc-color-text-tertiary)Deleted comment placeholder color
--asc-c-comment-item-timestamp-colorvar(--asc-color-text-tertiary)Relative timestamp color
--asc-c-comment-item-edited-badge-colorvar(--asc-color-text-tertiary)"(edited)" badge color
--asc-c-comment-item-action-btn-colorvar(--asc-color-text-secondary)Reply/edit/delete button color
--asc-c-comment-item-action-btn-hover-colorvar(--asc-color-text-primary)Action button hover color
--asc-c-comment-item-action-btn-danger-colorvar(--asc-color-status-error)Delete button color
--asc-c-comment-item-thread-line-colorvar(--asc-color-border)Vertical thread indent line color
--asc-c-comment-item-thread-line-hover-colorvar(--asc-color-border-strong)Thread line hover color

asc-comment-form

VariableFallbackDescription
--asc-c-comment-form-submit-bgvar(--asc-color-interactive)Submit button background
--asc-c-comment-form-submit-hover-bgvar(--asc-color-interactive-hover)Submit button hover background
--asc-c-comment-form-submit-colorvar(--asc-color-text-inverse)Submit button text color
--asc-c-comment-form-submit-radiusvar(--asc-border-radius-md)Submit button border radius
--asc-c-comment-form-textarea-bgvar(--asc-color-bg-surface)Textarea background color
--asc-c-comment-form-textarea-colorvar(--asc-color-text-primary)Textarea text color
--asc-c-comment-form-textarea-border-colorvar(--asc-color-border)Textarea border color
--asc-c-comment-form-textarea-focus-border-colorvar(--asc-color-border-focus)Textarea focus ring border color
--asc-c-comment-form-textarea-radiusvar(--asc-border-radius-md)Textarea border radius
--asc-c-comment-form-cancel-colorvar(--asc-color-text-secondary)Cancel button text color
--asc-c-comment-form-cancel-border-colorvar(--asc-color-border)Cancel button border color
--asc-c-comment-form-char-count-colorvar(--asc-color-text-tertiary)Character count indicator color

asc-vote-buttons

VariableFallbackDescription
--asc-c-vote-buttons-btn-colorvar(--asc-color-text-secondary)Vote button icon/text color
--asc-c-vote-buttons-btn-active-colorvar(--asc-color-interactive)Active (voted) button color
--asc-c-vote-buttons-btn-hover-bgvar(--asc-color-bg-muted)Vote button hover background
--asc-c-vote-buttons-btn-hover-colorvar(--asc-color-text-primary)Vote button hover text/icon color
--asc-c-vote-buttons-btn-radiusvar(--asc-border-radius-md)Vote button border radius

asc-comment-list

VariableFallbackDescription
--asc-c-comment-list-empty-colorvar(--asc-color-text-tertiary)Empty state text color
--asc-c-comment-list-skeleton-bgvar(--asc-color-bg-muted)Skeleton block background color
--asc-c-comment-list-load-more-colorvar(--asc-color-text-secondary)"Load more" button text color
--asc-c-comment-list-load-more-border-colorvar(--asc-color-border)"Load more" button border color

asc-reply-list

VariableFallbackDescription
--asc-c-reply-list-border-colorvar(--asc-color-border)Left-border color on the reply indent container
--asc-c-reply-list-load-btn-colorvar(--asc-color-interactive)"N replies" toggle button color
--asc-c-reply-list-load-btn-hover-colorvar(--asc-color-interactive-hover)"N replies" toggle button hover color
--asc-c-reply-list-load-more-colorvar(--asc-color-text-secondary)"Load more replies" button color