---
title: "Styling"
description: "How to style your OG Images."
canonical_url: "https://nuxtseo.com/docs/og-image/guides/styling"
last_updated: "2026-05-07T16:35:32.116Z"
---

Nuxt OG Image supports modern CSS via Tailwind v4, [UnoCSS](https://unocss.dev), and standard CSS. Your level of CSS support depends on the chosen renderer.

## Layout Support

<table>
<thead>
  <tr>
    <th>
      Feature
    </th>
    
    <th>
      <a href="/docs/og-image/renderers/takumi">
        Takumi
      </a>
    </th>
    
    <th>
      <a href="/docs/og-image/renderers/satori">
        Satori
      </a>
    </th>
    
    <th>
      <a href="/docs/og-image/renderers/browser">
        Browser
      </a>
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <strong>
        Flexbox
      </strong>
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        CSS Grid
      </strong>
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ❌
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Block/Inline
      </strong>
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ❌
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Position Absolute
      </strong>
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
</tbody>
</table>

### Satori Constraints

The [Satori](/docs/og-image/renderers/satori) renderer treats everything as a flexbox with `flex-direction: column` by default. It lacks support for `display: grid`, `display: block`, and `display: inline`.

### Takumi & Browser

The recommended [Takumi](/docs/og-image/renderers/takumi) and [Browser](/docs/og-image/renderers/browser) renderers offer much broader CSS support, including CSS Grid and standard block/inline layouts.

## Build-time Transformations

Nuxt OG Image performs "automagic" CSS transformations during the build process to ensure cross-renderer compatibility.

### CSS Downleveling & Polyfills

The module uses [Lightning CSS](https://lightningcss.dev/) to process styles for simpler renderers like Satori:

- **Color Downleveling:** Automatically converts modern colors (`oklch()`, `lab()`, `p3`) to standard hex or `rgba()`.
- **Logical Properties:** Expands properties like `padding-inline` and `margin-block` to physical counterparts.
- **Individual Transforms:** Merges `translate`, `rotate`, and `scale` into a single `transform` shorthand.
- **Color Mix:** Evaluates and replaces `color-mix()` functions with static color values.
- **Calc Evaluation:** Resolves simple `calc()` expressions at build time.

### Unsupported Classes

The build process filters out utility classes that static renderers don't support, such as animations, transitions, and z-index, to prevent rendering errors.

## Tailwind CSS & UnoCSS

Use Tailwind/UnoCSS classes directly in your templates without extra configuration.

```html
<div class="bg-blue-500 text-white p-12 flex flex-col items-center justify-center">
  <h1 class="text-6xl font-bold shadow-xl">Hello World</h1>
</div>
```

The module extracts classes from your OG components at build time and compiles them using your project's CSS engine.

### Theme Customizations

The module automatically resolves custom theme values, including Tailwind v4 variables defined in your `@theme` block:

```css [assets/css/main.css]
@import "tailwindcss";

@theme {
  --color-brand: #ff6600;
}
```

```html
<template>
  <div class="bg-brand text-white">
    Custom Theme Classes!
  </div>
</template>
```

### Auto-detection

The module automatically detects your CSS framework:

- **Tailwind v4:** Active if you install `tailwindcss` and use `@import "tailwindcss"` in your CSS.
- **UnoCSS:** Active if you enable `@unocss/nuxt`.
- **Nuxt UI v3:** Automatically imports colors and theme variables.

## Theme Switching (`data-theme`)

By default, OG images render with dark-mode semantic tokens (e.g. Nuxt UI's `bg-inverted`, `text-default`). To opt into theme-aware token resolution, set `data-theme` on the **root element** of your component. Tailwind v4 only.

### Static `data-theme`

Hard-code a theme on the root element:

```vue [components/OgImage/MyImage.satori.vue]
<template>
  <div data-theme="light" class="w-full h-full bg-default text-default p-10">
    <div class="bg-inverted text-inverted p-6 rounded-lg">
      Light mode tokens
    </div>
  </div>
</template>
```

Semantic tokens like `bg-inverted`, `text-muted`, `border-accented` resolve against the chosen theme: `data-theme="light"` produces light-mode values, `data-theme="dark"` produces dark-mode values.

### Dynamic `data-theme` (per-image color mode)

Bind `:data-theme` to a prop to swap themes per OG image:

```vue [components/OgImage/MyImage.satori.vue]
<script lang="ts" setup>
defineProps<{ colorMode?: 'light' | 'dark' }>()
</script>

<template>
  <div :data-theme="colorMode" class="w-full h-full bg-default text-default p-10">
    <div class="bg-inverted text-inverted p-6 rounded-lg">
      hello {{ colorMode }}
    </div>
  </div>
</template>
```

```vue [pages/light.vue]
<script setup lang="ts">
defineOgImage('MyImage', { colorMode: 'light' })
</script>
```

```vue [pages/dark.vue]
<script setup lang="ts">
defineOgImage('MyImage', { colorMode: 'dark' })
</script>
```

When the build detects a `:data-theme` binding on the root element, it resolves classes for both themes at build time and emits paired `bg-[#...] dark:bg-[#...]` arbitrary classes. The renderer then picks the correct value based on the `colorMode` prop you pass to `defineOgImage`.

<note>

The dynamic binding only works on the **root element** of the OG component. Nested elements inherit the resolved theme from the build pass.

</note>

<tip>

Templates that don't set `data-theme` keep the existing dark-mode default; this feature is opt-in and non-breaking.

</tip>

## Inline Styles

Use the `:style` binding for dynamic values that change based on props.

```html
<template>
  <div :style="{ backgroundColor: themeColor }" class="w-full h-full flex items-center justify-center">
    <h1 style="color: white; font-size: 80px;">
      {{ title }}
    </h1>
  </div>
</template>
```

## `<style>` tag support

You can use scoped or global `<style>` tags within your components. The module processes and applies these directly to the rendered image.

<note>

Standard CSS selectors work across all renderers, though Satori has limited support for advanced selectors like `:nth-child` or complex combinators.

</note>
