Skip to content

CSS Plugin

The CSS plugin automatically inlines, optimizes, and minifies your component styles using lightningcss. It’s enabled by default.

Define styles in your component:

@Component({
tag: 'my-button',
styles: `
button {
background: #007bff;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
}
`
})
export class MyButton extends HTMLElement {
render() {
return <button>Click me</button>;
}
}

Styles are automatically optimized and included in the compiled output.

The plugin handles three rendering modes:

Shadow DOM (shadow: true)

  • CSS is attached to the shadow root as-is
  • Provides full style encapsulation
  • :host and :host-context() work normally
@Component({
tag: 'my-component',
shadow: true, // CSS attached to shadowRoot
styles: css
})

Scoped (scoped: true)

  • CSS is transformed automatically for light DOM
  • :host selectors converted to light-DOM equivalents
  • All other selectors prefixed with your component tag (e.g., .buttonmy-component .button)
@Component({
tag: 'my-component',
scoped: true, // CSS automatically scoped
styles: css
})

Global (neither flag set)

  • CSS attached globally without transformations
  • Use for utility styles or reusable class definitions

To customize CSS processing:

import { defineConfig } from '@pencel/core';
export default defineConfig({
plugins: [
{
name: 'css',
options: {
enabled: true, // Enable/disable the plugin
scopedTransform: true // Enable automatic scoped transformations (default: true)
}
}
]
});

If you want scoped components but without automatic selector prefixing:

import { defineConfig } from '@pencel/core';
export default defineConfig({
plugins: [
{
name: 'css',
options: {
scopedTransform: false // Don't auto-prefix selectors
}
}
]
});