---
title: "@css / css()"
description: Styling utility to write nested style rules.
---

---

To style your website in Jaspr you need to write css styles alongside your html markup. See the [Styling](/concepts/styling) docs for a general overview of the different ways to add styling to your website.

The `css` utility gives you a convenient way of writing CSS style rules in Dart alongside your Jaspr components. It uses a combination of nested css selectors and Jasprs fully typed [CSS bindings](/api/utils/styles) in Dart.

---

## Registering style rules

When used as the `@css` annotation, you can register any amount of style definitions to be automatically rendered as CSS in your page.

```dart
@css
List<StyleRule> get styles => [
  // Style rules in here (covered in next section)
  /* ... */
];
```

The `@css` annotation can be applied to the following elements:

- global variables or static fields of type `List<StyleRule>`
- global or static getters returning `List<StyleRule>`

The recommended approach is to define your styles inside your components for better locality of your code:

```dart lib/app.dart
class App extends StatelessComponent {
  const App({super.key});

  @override
  Component build(BuildContext context) {
    return div(classes: 'main', [
      p([.text('Hello World')]),
    ]);
  }

  @css
  static List<StyleRule> get styles => [
    css('.main', [
      css('&').styles(
        width: 100.px,
        padding: Padding.all(10.rem),
      ),
      css('p').styles(
        color: Colors.blue,
      ),
    ]),
  ];
}
```

<Warning>
Styles defined in a component and registered using `@css` are **not** scoped to that component.
You should try to use ids or unique class names as selectors to prevent unwanted effects on other components or conflicting style definitions.
</Warning>

<Success>
**Tip:** The `jaspr_lints` package provides a convenient lint rule to keep your styles properties organized. Learn more about it [here](/api/linting#lint-rules).
</Success>

---

How the styles are rendered depends on your [Rendering Mode](/dev/modes):

<Tabs groupId="mode_combined">
  <TabItem value="static|server" label="Static & Server Mode">

    By default, your styles are rendered during the normal pre-rendering phase and embedded as an inline `<style>` element in your html output.

    You can change this behavior by using the `jaspr.styles = standalone` option in your `pubspec.yaml` file:

    ```yaml title="pubspec.yaml"
    jaspr:
      styles: standalone
    ```

    This will render all your styles to a separate CSS file and include a `<link>` to it in your html output during pre-rendering.

    <Warning>
      Files using `@css` will always be part of the server scope and therefore **cannot depend on client-only libraries** like `package:web` or `dart:js_interop`. Make sure to only use server-compatible libraries and packages (such as `package:universal_web`) in these files or your styles will not be rendered.
    </Warning>

  </TabItem>
  <TabItem value="client" label="Client Mode">

    In client mode, styles are rendered to a separate CSS file. You must include it in your HTML file by adding a `<link>` element for it.

    ```html title="web/index.html"
    <head>
      <link rel="stylesheet" href="main.css">
    </head>
    ```

    The name of the CSS file is defined by the [client entrypoint](/dev/client#client-entrypoint) file name, e.g. `lib/main.client.dart` will result in `main.css`.

    <Warning>
      When using `@css` in a file, it will be **executed using the Dart VM** during serve and build. This means you **cannot depend on client-only libraries** like `package:web` or `dart:js_interop` in these files. Make sure to only use vm-compatible libraries and packages (such as `package:universal_web`) in these files or your styles will not be rendered.
    </Warning>

  </TabItem>
</Tabs>

---

## Defining style rules

The default `css()` method takes a selector and calls [styles()](/api/utils/styles).

```dart
css('.main').styles(
  width: 100.px, 
  minHeight: 100.vh,
  color: Colors.black,
)
```

Which renders to:

```css
.main {
  width: 100px;
  min-height: 100vh;
  color: black;
}
```

### Nested style rules

Alternatively, calls of `css()` can take an additional list of nested rules like this:

```dart
css('.main', [
  css('&').styles(width: 100.px),
  css('&:hover').styles(backgroundColor: Colors.blue),
  css('p').styles(fontSize: 1.5em),
])
```

This renders to:

```css
.main {
  width: 100px;
}
.main:hover {
  background-color: blue;
}
.main p {
  font-size: 1.5em;
}
```

Nested style rules will be scoped to the parent. Using the `&` symbol as part of a child selector
refers to the parent selector.

Style rules can also be nested any level deep.

### Special style rules

In addition to the default style rule, the `css` utility also supports other rule variants:

#### css.import()

The `css.import()` function takes an url and renders a `@import` css rule:

```dart
css.import('https://fonts.googleapis.com/css?family=Roboto')
```

Renders to:

```css
@import url(https://fonts.googleapis.com/css?family=Roboto);
```

#### css.fontFace()

The `css.fontFace()` function renders a `@font-face` css rule.

```dart
css.fontFace(
  family: 'Roboto',
  style: FontStyle.italic,
  url: '/fonts/Roboto-italic.ttf',
)
```

Renders to:

```css
@font-face {
  font-family: "Roboto";
  font-style: italic;
  src: url(/fonts/Roboto-italic.ttf);
}
```

#### css.media()

The `css.media()` function renders a `@media` css rule.

```dart
css.media(MediaQuery.screen(minWidth: 1000.px), [
  css('.main').styles(width: 200.px),
])
```

Renders to:

```css
@media screen and (min-width: 1000px) {
  .main {
    width: 200px;
  }
}
```

