#css #web-framework #leptos #web


Scoped CSS for Rust web frameworks like leptos

8 releases

1.0.0-alpha Sep 26, 2023
0.3.2 Sep 19, 2023
0.3.1 Mar 29, 2023
0.2.2 Feb 28, 2023
0.1.0 Jan 24, 2023

#1336 in Web programming

Download history 7/week @ 2023-12-18 11/week @ 2023-12-25 34/week @ 2024-01-01 28/week @ 2024-01-08 29/week @ 2024-01-15 18/week @ 2024-01-22 25/week @ 2024-01-29 10/week @ 2024-02-05 15/week @ 2024-02-12 39/week @ 2024-02-19 66/week @ 2024-02-26 36/week @ 2024-03-04 69/week @ 2024-03-11 53/week @ 2024-03-18 195/week @ 2024-03-25 53/week @ 2024-04-01

376 downloads per month

MIT license

1.5K SLoC


  • Scoped CSS for Rust web frameworks like Leptos.
  • style! macro is for writing css inside rust functions directly. It will validates css properties as well.
  • style_sheet! macro is for writing css in external css file and importing that inside rust functions.
  • style_str! macro is same as style! macro but returns the tuple (class_name, style_val) instead of saving the style_val to the separate file.
  • style_sheet_str! this same as style_sheet! macro but returns the tuple (class_name, style_val) instead of saving the style_val to the separate file.

Important Note

  • This Readme file is for the latest relase of stylers 1.0.0-alpha. You can find the readme for previous versions here


cargo add stylers


  • If you are using style or style_sheet macro, then you have to add the stylers crate as both dependencies and build-dependencies in your Cargo.toml file.
stylers = { version = "*" }

stylers = {  version = "*" }
  • Then you have to add build.rs file in your root directory and add the below code snippet in it.
use stylers::build;

fn main() {
  • In the above case output css file will be generated in the ./target/main.css path. You can include that main.css file in your index.html file.(Or If you are using a build like Trunk.rs you have to follow appropriate methods to include the main.css file to your project).

You can find the importance of these new changes here.

Leptos Example

Note :Leptos version > 0.4.9 has some new changes. But stylers works the same way in all versions of leptos


fn Hello(cx: Scope, name: &'static str) -> impl IntoView {
    let styler_class = style! {
            color: blue;
            color: red;
            content: raw_str(r#"\hello"#);
            font: "1.3em/1.2" Arial, Helvetica, sans-serif;
        div {
            border: 1px solid black;
            margin: 25px 50px 75px 100px;
            background-color: lightblue;
        h2 {
            color: purple;
        @media only screen and (max-width: 1000px) {
            h3 {
                background-color: lightblue;
                color: blue

    view! {cx, class = styler_class,
        <div class="one">
            <h1 id="two">"Hello"</h1>
            <h3>"Hello Kanna"</h3>


fn Hello(cx: Scope, name: &'static str) -> impl IntoView {
    let class_name = style_sheet!("./hello.css");
    view! {cx, class = class_name,
        <div class="one">
            <h1 id="two">"Hello"</h1>
  • In the above case hello.css file is inside the root directory of the project.


pub fn GreenButton(cx: Scope) -> impl IntoView {
    let (class_name, style_val) = style_str! {
        button {
            background-color: green;
            border-radius: 8px;
            border-style: none;
            box-sizing: border-box;
            color: yellow;
            cursor: pointer;
            display: inline-block;
            font-family: r#"Haas Grot Text R Web"#, r#"Helvetica Neue"#, Helvetica, Arial, sans-serif;
            font-size: 14px;
            font-weight: 500;
            height: 40px;
            line-height: 20px;
            list-style: none;
            margin: 0;
            outline: none;
            padding: 10px 16px;
            position: relative;
            text-align: center;
            text-decoration: none;
            transition: color 100ms;
            vertical-align: baseline;
            user-select: none;
            -webkit-user-select: none;
            background-color: yellow;
            color: green;

    view! {cx, class = class_name,
        <button>"I am green button"</button>


pub fn BlueButton(cx: Scope) -> impl IntoView {
    let (class_name, style_val) = style_sheet_str!("./src/button.css");

    view! {cx, class = class_name,
        <button>"I am blue button"</button>
  • In this case button.css file is inside the src directory of the project.

Custom pseudo classes

  • In some situations we may need our css to affect deep down the dom tree. To achieve this we have custom pseudo class called :deep(). For example below css is valid one.


div :deep(h3) {
    color: orange;


div.l-243433 h3{color: orange;}
  • If you want your particular css to be global you can use :deep() directive without any prceding selectors it.


:deep(h3 div) {
    color: orange;


h3 div{color: orange;}

How it works:

  • This stylers::build method will parse all the rust files in the path /src/**/*.rs during build step to find the places the style and style_sheet macros has been used and generate single output css file.
  • style_str and style_sheet_str directly returns the tuple (class_name, output_css).

Edge cases handled for style! macros

  • By default double quotes ( " ) around css property values will be removed. If user wants to retain the double quotes they have to wrap it using raw_str as given below:
  • these rules apply for both style! and style_str! macros


        content: raw_str(r#"\hello"#);
        font: "1.3em/1.2" Arial;


        content: "\hello";
        font: 1.3em/1.2 Arial;

Optional build process using Trunk(Only when you use style! or style_sheet! macro )

  • You have to include generated main.css in the index.html (e.g <link rel="stylesheet" href="/main.css">).

  • In Trunk.toml you have to add the below lines to move the the main.css file from ./target/ directory to ./dist/ directory.

stage = "post_build"
command = "sh"
command_arguments = ["-c", "cp ./target/main.css $TRUNK_STAGING_DIR/"]
  • when you are including external css file using style_sheet! macro, whenever you make some changes in your css file you have to save corresponding rust file(*.rs) for css to be updated on the browser. For more info about trunk refer here.
  • if something is odd with styling, delete the ./target/stylers directory and rebuild your package. If the problem persists please raise an issue here.


~31K SLoC