# 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 } `/> ```