Styling-with-class-Macro[20260803230613]

0 阅读1分钟

使用 class! 宏进行样式设计

项目代码:github.com/euv-dev/euv

class! 宏简介

class! 宏是 euv 在 Rust 代码中直接编写 CSS 的解决方案。无需在 .rs.css 文件之间切换,你可以在 class! 宏中使用类似 CSS 的语法定义样式。该宏会将你的样式编译为 CSS 并在运行时注入到页面中,提供作用域样式而无需单独的构建步骤。

基本 CSS 类定义

class! 宏让你使用熟悉的语法定义 CSS 类。每个类用一个名称和一组属性-值对来声明:

class! {
    pub c_card {
        display: "flex";
        padding: "10px";
    }
}

在这个示例中,c_card 是一个公开 CSS 类,设置 displayflexpadding10pxpub 关键字使类可以在组件中访问。

多个类

你可以在一个 class! 块中定义多个类:

class! {
    pub c_card {
        display: "flex";
        padding: "10px";
    }
    pub c_header {
        font-size: "24px";
        font-weight: "bold";
    }
    pub c_body {
        font-size: "14px";
        color: "#666";
    }
}

伪类和嵌套选择器

class! 宏使用嵌套块来支持伪类。伪类以 : 为前缀,定义在所属的类内部:

class! {
    pub c_card_hover {
        ":hover" {
            background: "#4338ca";
        }
    }
}

这会为 .c_card_hover:hover 生成一个 CSS 规则,背景色为 #4338ca。你可以使用任何 CSS 伪类,如 :hover:focus:active:first-child:last-child 等。

多个伪类

一个类可以有多个伪类:

class! {
    pub c_button {
        padding: "8px 16px";
        border: "none";
        cursor: "pointer";

        ":hover" {
            background: "#4338ca";
        }
        ":active" {
            background: "#3730a3";
        }
        ":focus" {
            outline: "2px solid #818cf8";
        }
    }
}

在组件中使用类

要在组件中使用 class! 定义的类,在 html! 宏中引用它:

class! {
    pub c_card {
        display: "flex";
        padding: "10px";
    }
}

fn app() -> VirtualNode {
    html! {
        div {
            class: c_card
            h3 { "Card Title" }
            p { "Card content goes here." }
        }
    }
}

class: c_card 属性将 c_card CSS 类应用到 div 元素上。

内置动画

euv 提供了一组预定义的 CSS 关键帧动画,可以直接使用:

动画描述
euv-spin将元素旋转 360 度
euv-fade-in将元素从透明渐变到不透明
euv-scale-in将元素从小缩放到正常大小
euv-pulse创建脉冲透明度效果
euv-slide-up将元素从下方滑入视图
euv-slide-left将元素从左侧滑入视图
euv-fade-in-up结合淡入和上滑效果
euv-progress创建进度条动画
euv-shimmer创建闪烁加载效果

要使用这些动画,只需将其作为类应用:

html! {
    div {
        class: euv-fade-in
        p { "This element fades in when it appears." }
    }
}

自定义关键帧动画

如果内置动画不满足需求,你可以使用 Css::inject_css() 创建自定义关键帧动画:

// 注入自定义 CSS 关键帧
Css::inject_css(r#"
    @keyframes my-custom-animation {
        from {
            opacity: 0;
            transform: translateY(20px);
        }
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }
    .my-custom-class {
        animation: my-custom-animation 0.5s ease-out;
    }
"#);

这让你可以完全控制动画效果,同时保持 CSS-in-Rust 的方式。

CSS 过渡

除了关键帧动画,你还可以使用 CSS 过渡来实现平滑的属性变化。在 class! 块中定义过渡:

class! {
    pub c_transition_box {
        background: "#f0f0f0";
        transition: "background 0.3s ease";

        ":hover" {
            background: "#4338ca";
        }
    }
}

这在悬停时创建一个平滑的颜色过渡效果。

完整样式示例

下面是一个完整的示例,展示了各种样式特性:

use euv::*;

class! {
    pub c_app_container {
        display: "flex";
        flex-direction: "column";
        align-items: "center";
        padding: "20px";
    }
    pub c_title {
        font-size: "28px";
        font-weight: "bold";
        margin-bottom: "16px";
    }
    pub c_card {
        display: "flex";
        flex-direction: "column";
        padding: "16px";
        border: "1px solid #e5e7eb";
        border-radius: "8px";
        max-width: "400px";
        transition: "box-shadow 0.2s ease";

        ":hover" {
            box-shadow: "0 4px 12px rgba(0, 0, 0, 0.1)";
        }
    }
    pub c_button {
        padding: "10px 20px";
        background: "#4338ca";
        color: "#ffffff";
        border: "none";
        border-radius: "6px";
        cursor: "pointer";
        transition: "background 0.2s ease";

        ":hover" {
            background: "#3730a3";
        }
    }
}

fn app() -> VirtualNode {
    html! {
        div {
            class: c_app_container
            h1 {
                class: c_title
                "euv Styling Demo"
            }
            div {
                class: c_card
                p { "This card uses the class! macro for styling." }
            }
            div {
                class: euv-fade-in
                p { "This element uses a built-in animation." }
            }
        }
    }
}

mount("#app", app);

总结

class! 宏提供了一种强大且便捷的方式来管理 euv 中的样式:

  • CSS 类定义:使用 pub class_name { property: "value"; } 定义类
  • 伪类:使用嵌套块如 ":hover" { ... } 实现交互状态
  • 内置动画:使用 euv-spineuv-fade-ineuv-scale-ineuv-pulseeuv-slide-upeuv-slide-lefteuv-fade-in-upeuv-progresseuv-shimmer
  • 自定义动画:通过 Css::inject_css() 创建自定义关键帧
  • CSS 过渡:在类定义中添加平滑的属性过渡
  • 在模板中使用:在 html! 宏中通过 class: class_name 应用类

通过 class! 宏,你可以将样式与组件保持在一起,使 UI 外观的维护和推理变得更加容易。


项目代码:github.com/euv-dev/euv