# 🎨 Dioxus Style
**The Ultimate Styling Solution for Dioxus**
*Type-Safe. Compile-Time. SCSS-Powered.*
[](https://crates.io/crates/dioxus_style)
[](https://docs.rs/dioxus_style)
[](LICENSE-MIT)
---
## 🧐 Why Dioxus Style?
Writing CSS in Rust often feels like a compromise. You either have to use loose strings (`class: "btn primary"`) which hides typos until runtime, or use heavy runtime libraries that slow down your app.
**Dioxus Style changes the game:**
1. **🛡️ Zero Runtime Cost (Almost)**: Your SCSS is compiled to CSS **during the build**. The browser just loads a static CSS string.
2. **✅ Type Safety**: Your CSS classes become **Rust Constants**. If you type `style::buttn` instead of `style::button`, your code **won't compile**. No more UI bugs because of a typo!
3. **💪 SCSS Built-In**: Use variables, nesting, and mixins right out of the box. No external build tools needed.
4. **⚡ Hot Reload Friendly**: Change your `.scss` file, and the app updates instantly.
---
## 📦 Installation
Add this to your `Cargo.toml`.
```toml
[dependencies]
dioxus_style = "0.5.3"
```
*Note: SCSS support is enabled by default. If you only want CSS, you can disable default features.*
---
## 🚀 Step-by-Step Guide
### 1. Create your SCSS file
Create a standard SCSS file anywhere in your project (e.g., `src/button.scss`).
```scss
// src/button.scss
$primary: #6200ea;
.container {
display: flex;
gap: 10px;
}
.btn {
background-color: $primary;
color: white;
padding: 8px 16px;
border-radius: 4px;
&:hover {
opacity: 0.9;
}
// Defines a modifier class
&.outlined {
background: transparent;
border: 2px solid $primary;
color: $primary;
}
}
```
### 2. Connect it to your Component
Use the `#[with_css]` macro to load the file. This does two things:
1. Compiles the SCSS to Scoped CSS.
2. Creates a Rust module (named `style` in the example below) containing your classes.
```rust
use dioxus::prelude::*;
use dioxus_style::with_css;
// usage: #[with_css(MODULE_NAME, "PATH_TO_FILE")]
#[with_css(style, "src/button.scss")]
fn ButtonComponent() -> Element {
// ...
}
```
### 3. Use Type-Safe Classes
Now, instead of typing strings, you use the module you just created!
```rust
#[with_css(style, "src/button.scss")]
fn ButtonComponent() -> Element {
rsx! {
div {
// style::container is a constant derived from your SCSS file!
class: style::container,
button {
class: style::btn,
"Primary Button"
}
button {
// ✨ MAGIC: Combine classes using the '+' operator
class: style::btn + style::outlined,
"Outlined Button"
}
}
}
}
```
---
## 🧠 Deep Dive: How it works
### The Magic of `style::btn`
When you write `.btn { ... }` in your SCSS, the macro generates Rust code that looks like this:
```rust
// Generated automatically by the macro
mod style {
pub const btn: CssClass = CssClass::new("sc_X7z9_btn");
pub const outlined: CssClass = CssClass::new("sc_X7z9_outlined");
// ...
}
```
This means:
- **Autocomplete**: Your IDE knows exactly what classes exist.
- **Refactoring**: Rename a class in SCSS? The compiler tells you where you need to update your Rust code.
### Automatic Scoping
To prevent styles from leaking (e.g., a `.container` in one component affecting another), `dioxus_style` generates unique hashes.
- Input: `.btn`
- Output: `.sc_a1b2_btn`
You never have to worry about class name collisions again.
---
## 🛠️ Advanced Usage
### Multiple Stylesheets
If you have a complex component that needs styles from multiple files (e.g., a shared theme and specific component styles), use `component_with_css!`.
```rust
use dioxus_style::component_with_css;
component_with_css! {
// Import multiple files into different namespaces
layout: "src/styles/layout.scss",
theme: "src/styles/theme.scss",
fn Dashboard() -> Element {
rsx! {
div {
class: layout::grid, // From layout.scss
div {
// Combine classes from different files!
class: layout::card + theme::dark_mode,
"Multi-styled Component"
}
}
}
}
}
```
### Manual/Inline Scoping
For one-off styles where you don't want a separate file.
```rust
use dioxus_style::scoped_style;
fn InlineExample() -> Element {
// Compiles SCSS string immediately
scoped_style!(css, "
.text { color: red; font-weight: bold; }
");
rsx! {
p { class: css::text, "I am styled inline!" }
}
}
```
---
## ❓ Frequently Asked Questions
**Q: Does this work with Tailwind?**
A: Yes, you can use both. `dioxus_style` is great for custom complex components where Tailwind strings get too long, or for utilizing SCSS features.
**Q: Where do I put my SCSS files?**
A: Anywhere! Paths are relative to your `Cargo.toml`. Common patterns are `src/components/MyComponent.scss` or a dedicated `assets/` folder.
**Q: I don't see my styles?**
A: Make sure you have `style { dangerous_inner_html: "{inject_styles()}" }` in your root App component if you are NOT using the `#[with_css]` macro on the root. (Note: `#[with_css]` handles injection for you automatically in the component usage, but global styles usually need a root injector).
---
## 📜 License
This project is dual-licensed under MIT and Apache 2.0.