#[css_module]prelude only.Expand description
Generate type-safe styles with scoped CSS class names.
The css_module attribute macro creates scoped CSS modules that prevent class name collisions
by making each class globally unique. It expands the annotated struct to provide type-safe
identifiers for your CSS classes, allowing you to reference styles in your Rust code with
compile-time guarantees.
§Syntax
The css_module attribute takes:
- The asset string path - the absolute path (from the crate root) to your CSS file.
- Optional
AssetOptionsto configure the processing of your CSS module.
It must be applied to a unit struct:
#[css_module("/assets/my-styles.css")]
struct Styles;
#[css_module("/assets/my-styles.css", AssetOptions::css_module().with_minify(true))]
struct Styles;§Generation
The css_module attribute macro does two things:
- It generates an asset and automatically inserts it as a stylesheet link in the document.
- It expands the annotated struct with snake-case associated constants for your CSS class names.
// This macro usage:
#[css_module("/assets/mycss.css")]
struct Styles;
// Will expand the struct to (simplified):
struct Styles {}
impl Styles {
// Snake-cased class names can be accessed like this:
pub const your_class: &str = "your_class-a1b2c3";
}§CSS Class Name Scoping
The macro only processes CSS class selectors (.class-name). Other selectors like IDs (#id),
element selectors (div, p), attribute selectors, etc. are left unchanged and not exposed as
Rust constants.
The macro collects all class selectors in your CSS file and transforms them to be globally unique
by appending a hash. For example, .myClass becomes .myClass-a1b2c3 where a1b2c3 is a hash
of the file path.
Class names are converted to snake_case for the Rust constants. For example:
.fooBarbecomesStyles::foo_bar.my-classbecomesStyles::my_class
To prevent a class from being scoped, wrap it in :global():
/* This class will be scoped */
.my-class { color: blue; }
/* This class will NOT be scoped (no hash added) */
:global(.global-class) { color: red; }
/* Element selectors and other CSS remain unchanged */
div { margin: 0; }
#my-id { padding: 10px; }§Using Multiple CSS Modules
Multiple css_module attributes can be used in the same scope by applying them to different structs:
// First CSS module
#[css_module("/assets/styles1.css")]
struct Styles;
// Second CSS module with a different struct name
#[css_module("/assets/styles2.css")]
struct OtherStyles;
// Access classes from both:
rsx! {
div { class: Styles::container }
div { class: OtherStyles::button }
}§Asset Options
Similar to the asset!() macro, you can pass optional AssetOptions to configure processing:
#[css_module(
"/assets/mycss.css",
AssetOptions::css_module()
.with_minify(true)
.with_preload(false)
)]
struct Styles;§Example
First create a CSS file:
/* assets/styles.css */
.container {
padding: 20px;
}
.button {
background-color: #373737;
}
:global(.global-text) {
font-weight: bold;
}Then use the css_module attribute:
use dioxus::prelude::*;
fn app() -> Element {
#[css_module("/assets/styles.css")]
struct Styles;
rsx! {
div { class: Styles::container,
button { class: Styles::button, "Click me" }
span { class: Styles::global_text, "This uses global class" }
}
}
}