css Utility
For stylesheets that need to change dynamically in response to state or property updates, WebComponent provides the css tagged template literal. This utility lets you inject reactive functions and Markup helpers directly into your CSS code.
How it Works
The css tag returns an instance of the CSSStyle class. Under the hood, any function interpolated inside the template literal is automatically wrapped in a Markup effect.
When any reactive prop or state getter is called inside these functions, it registers as a dependency. Whenever those dependencies change, the effect re-runs, and WebComponent updates the component's adopted stylesheets dynamically without recreating the stylesheet element.
Practical Example
In the following example, the background and text color of the badge change reactively based on the value of the status prop.
1import { WebComponent, html, css } from '@beforesemicolon/web-component'2 3class StatusBadge extends WebComponent {4 static observedAttributes = ['status']5 status = 'info'6 7 stylesheet = css`8 :host {9 display: inline-block;10 padding: 0.25rem 0.5rem;11 border-radius: 4px;12 font-size: 0.875rem;13 font-weight: bold;14 15 /* Reactive styles */16 background-color: ${() =>17 this.props.status() === 'success' ? '#d4edda' : '#e2e3e5'};18 color: ${() =>19 this.props.status() === 'success' ? '#155724' : '#383d41'};20 }21 `22 23 render() {24 return html`<slot></slot>`25 }26}27 28customElements.define('status-badge', StatusBadge)Using Markup Helpers (when & is)
To make dynamic styling cleaner, you can use @beforesemicolon/markup's reactive helpers like when() and is() directly inside your style strings. They return reactive functions that resolve values dynamically.
is(getter, expectedValue): Checks if a getter returns a matching value.when(condition, thenValue, otherwiseValue): Evaluates a condition (can be a getter or a function) and returns the corresponding value.
Here is the same example using these helpers:
1import {2 WebComponent,3 html,4 css,5 when,6 is,7} from '@beforesemicolon/web-component'8 9class StatusBadge extends WebComponent {10 static observedAttributes = ['status']11 status = 'info'12 13 stylesheet = css`14 :host {15 display: inline-block;16 padding: 0.25rem 0.5rem;17 border-radius: 4px;18 19 /* Using when & is helpers */20 background-color: ${when(21 is(this.props.status, 'success'),22 '#d4edda',23 '#e2e3e5'24 )};25 color: ${when(26 is(this.props.status, 'success'),27 '#155724',28 '#383d41'29 )};30 }31 `32 33 render() {34 return html`<slot></slot>`35 }36}The CSSStyle Class
The css function parses the strings and values into a CSSStyle instance. The class has the following public API:
toString(): Evaluates and returns the stylesheet as a plain CSS string.onUpdate(callback): Registers a callback function that is invoked with the updated CSS string whenever any interpolated reactive values change.
1import { css } from '@beforesemicolon/web-component'2 3const themeColor = state('blue')4 5const style = css`6 button {7 background-color: ${() => themeColor[0]()};8 }9`10 11style.onUpdate((newCss) => {12 console.log('CSS updated:', newCss)13})WebComponent hooks into the onUpdate method automatically, meaning you rarely need to call onUpdate manually in your application.