---
# System prepended metadata

title: CSS in Marko

---

# CSS in Marko

## External Stylesheets

### Autodiscovered

Css files are automatically discovered according to Marko's naming conventions.

_style.css_
```css
.foo {
    color: red;
}
```

_index.marko_
```htmlembedded
<div class="foo"/>
```

### Imported

Css files can also be explicitly imported:

_something.css_
```css
.foo {
    color: red;
}
```

_index.marko_
```htmlembedded
import "./something.css";

<div class="foo"/>
```

### CSS Modules

Since you have to use Marko with a bundler and most bundlers are autoconfigured to support css modules for `.module.css`, this should work out of the box.  If it is not supported by a bundler there is almost certainly a plugin.

The above methods of including css add the styles globally. CSS Modules allow you to import a css file with scoped class names, so they won't conflict with other styles:

_something.module.css_
```css
.foo {
    color: red;
}
```

_index.marko_
```htmlembedded
import styles from "./something.module.css";
<div class=styles.foo/>
```

## `<style>`

Style tags are externalized as separate css files.

```htmlembedded
<style>
    .foo {
        color: red;
    }
</style>

<div class="foo"/>
```

### CSS Modules

If you want scoped styles, you can opt-in to CSS Modules by using a tag variable.  This requires your bundler to support it, but again, it should work out of the box.

```htmlembedded
<style/style>
    .foo {
        color: red;
    }
</style>

<div class=style.foo/>
```

### Future: Interpolated Values

If you want dynamic styles, just interpolate in a value:

```htmlembedded
<style>
    .foo {
        color: ${input.color};
    }
</style>
<div class="foo"/>
```

Marko will compile this to a css custom property and define that property for the component:

```htmlembedded
<style>
    .foo {
        color: var(--color_kjh4kj24);
    }
</style>
<div class="foo" style=`--color_kjh4kj24: ${input.color}`/>
```

<details>
<summary>However...</summary>
    
Depending on the analysis done we may not know which node to apply the `style` attribute to.  Dylan has [suggested](https://discord.com/channels/725013179465203793/725021901457457193/987830452247232523) we compile to somrthing like this for the general case:

```htmlembedded
<!--bundled-->
<style>
    .foo {
        color: var(--color_kjh4kj24);
    }
</style>
<!--inline-->
<style class="tjk23kj234kj23">
  .tjk23kj234kj23 ~ * {
    --color_kjh4kj24: ${input.color}
  }
</style>
```

The first style with the user's css is bundled as an external file.  If there are dynamic values injected, a `<style>` tag is inlined in the output HTML to define those static values.
    
Concerns: 
- Selector performance
- Recursive components with different dynamic values

</details>

## Future: `#css`

We have introduced the concept of directives: compile-time attributes.  The `#css` directive would compile to pull its contents out into a `<style>` block that uses CSS Modules, and apply the resulting `class` (and a `style` attribute if there are dynamic values).
    
```
<div #css=`color: ${input.color}`/>
```
    
compiles to 

```
<style/style_fj2b>
    .lksdf32n {
        color: var(--color_kjh4kj24);
    }
</style>
<div 
    class=style_fj2b.lksdf32n 
    style=`--color_kjh4kj24: ${input.color}`
/>
```

If you enable PostCSS plugins that support nesting (or any other features), those become available within the `#css` directive:
    
```
<a #css=`
   color: $blue_400; 
   &:hover { 
       color: $blue_600
   }
`/>
```
