> For the complete documentation index, see [llms.txt](https://docs.aurelia.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.aurelia.io/~/revisions/NShYVVc01DvYc5bgBiwq/developer-guides/scenarios/css-in-js-with-emotion.md).

# CSS-in-JS with Emotion

## What is CSS-in-JS?

CSS-in-JS is a styling technique where JavaScript is used to style components. When this JavaScript is parsed, CSS is generated (usually as an `<style>` element) and attached to the DOM. It allows you to abstract CSS to the component level, using JavaScript to describe styles in a declarative and maintainable way.

This method is very common in the ecosystem of some client-side libraries, such as React. So we decided to discuss how to use CSS-in-JS in Aurelia.

## Why EmotionJS?

There are multiple implementations of CSS-in-JS concept in the form of libraries, but few of them are framework-agnostic, so we chose [EmotionJS](https://github.com/emotion-js/emotion)

Emotion, as described on its site, says:

> Emotion is a performant and flexible CSS-in-JS library. Building on many other CSS-in-JS libraries, it allows you to style apps quickly with string or object styles. It has a predictable composition to avoid specificity issues with CSS. With source maps and labels, Emotion has a great developer experience and great performance with heavy caching in production.

## EmotionJS & Aurelia 2 integration

To integrate EmotionJS and Aurelia, Follow the steps below: Add EmotionJS framework-agnostic version to your project with the following command

```bash
npm i emotion --save
```

Define a custom attribute and name it Emotion, just like the following code

```typescript
import { inject } from "aurelia";
import { css, cache } from 'emotion'
@inject(Element)
export class EmotionCustomAttribute {
    constructor(private element: Element) {
    }
    attached() {
        if (this.isInShadow(this.element))
            cache.sheet.container = this.element.getRootNode() as HTMLElement;
        else
            cache.sheet.container = document.head;
        this.element.classList.add(css(this.value));
    }
    private isInShadow(element: Element): boolean {
        return element.getRootNode() instanceof ShadowRoot;
    }
}
```

**What is isInShadow?** This method helps us to find out if our HTMLElement is inside of a shadow-root or not.

**Why does shadow-root matter?** Because Aurelia 2 supports ShadowDOM, we need to style those HTMLElements inside a shadow via the emotion library.

**What is cache.sheet.container?** The emotion library uses container configuration to inject styles into specific DOM. To support shadow-root, we should inject our styles into the shadow block but for global styles `document.head` is good.

**Why did we choose attached?** Detecting ShadowDOM mode for an HTMLElement is possible via this life-cycle method.

Now, Register the new Emotion custom attribute in your main.ts file.

```typescript
import Aurelia from 'aurelia';
import { MyApp } from './my-app';
import { EmotionCustomAttribute } from './emotion-attr';
Aurelia
  .register(EmotionCustomAttribute)
  .app(MyApp)
  .start();
```

Add an object in your view model and call it cssObject.

```typescript
export class MyApp {
  public message = 'Hello World!';
  private color = 'white'
  public cssObject = {
    backgroundColor: 'hotpink !important',
    '&:hover': {
      color: this.color
    }
  };
}
```

Go to your view and add emotion custom attribute to an HTML tag.

```html
<div class="message" emotion.bind="cssObject">${message}</div>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.aurelia.io/~/revisions/NShYVVc01DvYc5bgBiwq/developer-guides/scenarios/css-in-js-with-emotion.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
