---
title: CSS Presets
description: Define reusable CSS themes for your organization and inject them into any Myop component at render time with the SDK's injectCss loader option.
keywords: [myop css presets, injectCss, loaderOptions, org themes, component theming, style presets]
---
# CSS Presets

CSS presets are named CSS themes you define once for your organization and inject into any Myop
component at render time. A component written by one team can then be previewed — or shipped —
under your brand's colors, spacing, and typography without touching its source.

Under the hood a preset is just a string of CSS. The SDK appends it to the component's `<head>`
inside a `<style>` tag before the component's iframe is written, so it is present on first paint
(no flash of unstyled content) and lands last in the cascade, where it wins over the component's
own styles by normal cascade order.

## Defining presets

Presets live at the organization level and are managed by org admins in the dashboard, under
**Settings → CSS presets**. Each preset has a name and a body of CSS.

Reads are open to every member of the org — anyone can preview a component under a preset — but
only admins can add, edit, or delete them.

## Using a preset in the SDK

Pass the preset's CSS to a component through the `injectCss` loader option:

```typescript
await myop.renderComponent('my-component-id', container, {
  injectCss: `
    :root {
      --brand-bg: #15151f;
      --brand-fg: #d6d6f5;
    }
    body {
      background: var(--brand-bg);
      color: var(--brand-fg);
    }
  `,
});
```

`injectCss` is a plain string, so it composes with anything — a preset fetched from your org, a
theme you compute at runtime, or a hard-coded stylesheet.

### React

```tsx
<MyopV2ReactComponent
  componentId="my-component-id"
  loaderOptions={{ injectCss: theme.css }}
/>
```

## Previewing presets in the component builder

The component builder has a **Style presets** section in its left panel. It lists your org's
presets as chips; clicking one re-renders the preview with that CSS injected, and **Off** returns
the component to its own styles. This is the fastest way to check that a component survives every
theme your organization uses before you publish it.

Presets are fetched the first time you open that section, not on page load, so components you
never theme cost nothing extra.

## Writing good preset CSS

Prefer **design tokens** over blanket overrides:

```css
/* Good — composes with the component's own styles */
:root {
  --myop-bg: #15151f;
  --myop-fg: #d6d6f5;
  --myop-accent: #9747ff;
}

/* Fragile — fights every component and breaks on any markup change */
div.card > span:nth-child(2) {
  color: #d6d6f5 !important;
}
```

A preset built from custom properties degrades gracefully: a component that doesn't consume a token
simply ignores it. A preset built from deep selectors and `!important` silently breaks the moment a
component's internal markup changes.

:::tip
Because the injected `<style>` is appended last in `<head>`, you rarely need `!important` at all.
Normal cascade order already puts your preset ahead of the component's own rules at equal specificity.
:::

## Constraints

| Limit | Value |
|---|---|
| Preset name | 200 characters |
| Preset CSS | 100,000 characters |

Preset CSS may not contain a closing `</style>` tag. Because the CSS is injected as the contents of
a `<style>` element — an HTML raw-text element — that sequence would terminate the tag early and
allow arbitrary markup to be injected into the component's frame. The server rejects it on write and
the SDK neutralizes it on read. No legitimate stylesheet contains it.

## Related

- [System Architecture](/docs/learnMyop/systemArchitecture)
- [HTML Components](/docs/learnMyop/HTMLComponent)
