# HTML Linked With Scoped CSS
```elixir
Mix.install([
{:lumis, path: ".."}
])
```
`formatter: :html_linked` renders classes instead of inline styles. This is useful when your app has a strict Content Security Policy or when many code blocks share the same stylesheet.
```elixir
code = """
defmodule Demo do
def hello(name), do: "hello #{name}"
end
"""
html =
Lumis.highlight!(code,
formatter: {:html_linked, language: "elixir"}
)
```
The generated HTML contains semantic token classes:
```elixir
html
```
Build CSS for the light theme:
```elixir
light_css = Lumis.Theme.build_css!("github_light")
```
By default, Lumis emits the same selector shape as the bundled CSS files:
```css
.lumis {
color: #1f2328;
background-color: #ffffff;
}
.l-keyword {
color: #cf222e;
}
```
Use `:container_selector` when your code block uses a different wrapper class. This changes only the container rule selector:
```elixir
Lumis.Theme.build_css!("github_light",
container_selector: ".code-block"
)
```
Output shape:
```css
.code-block {
color: #1f2328;
background-color: #ffffff;
}
.l-keyword {
color: #cf222e;
}
```
Use `:scope` to put every selector under a parent selector. This is commonly used for manual dark mode selectors:
```elixir
dark_css =
Lumis.Theme.build_css!("github_dark",
scope: ~s(html[data-theme="dark"]),
container_selector: ".lumis",
container_style: [
{"background-color", "var(--code-background)"},
{"border-radius", "0.375rem"},
{"padding", "1rem"},
{"overflow-x", "auto"}
]
)
```
Output shape:
```css
html[data-theme="dark"] .lumis {
color: #e6edf3;
background-color: var(--code-background);
border-radius: 0.375rem;
padding: 1rem;
overflow-x: auto;
}
html[data-theme="dark"] .l-keyword {
color: #ff7b72;
}
```
You can combine light and dark CSS and embed or serve the result however your application needs:
```elixir
css = light_css <> "\n\n" <> dark_css
```