第七章:样式与 Tailwind CSS

博客v1.0系列教程(Dioxus)博客 v1.0 系列教程 (Dioxus)

第七章:样式与 Tailwind CSS

1. Dioxus 样式方案

rsx! {
    // 方案一:内联 style(适合动态值)
    div { style: "color: red; font-size: 16px;", "红色文字" }

    // 方案二:class 类名(适合静态样式)
    div { class: "text-red-500 text-base", "红色文字" }

    // 方案三:CSS 变量(适合主题系统)
    div { style: "color: var(--text); background: var(--card);", "主题色文字" }
}

2. 内联样式

2.1 字符串形式

#[component]
fn DynamicBox(color: Signal<String>, size: Signal<u32>) -> Element {
    rsx! {
        div {
            style: "
                background: {color};
                width: {size}px;
                height: {size}px;
                border-radius: {if size() > 50 { \"12px\" } else { \"4px\" }};
                transition: all 0.3s;
            ",
            "动态盒子"
        }
    }
}

2.2 条件样式

rsx! {
    button {
        class: "px-4 py-2 rounded-lg",
        style: "
            background: {if primary() { \"var(--primary)\" } else { \"var(--card)\" }};
            color: {if primary() { \"white\" } else { \"var(--text)\" }};
            opacity: {if disabled() { \"0.5\" } else { \"1\" }};
            cursor: {if disabled() { \"not-allowed\" } else { \"pointer\" }};
        ",
        "按钮"
    }
}

3. Tailwind CSS 集成

3.1 CDN 方式(开发用)

public/index.html 中添加:

<script src="https://cdn.tailwindcss.com"></script>

3.2 常用工具类

// 布局
class: "flex items-center justify-between"
class: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"
class: "space-y-4"

// 间距
class: "p-4 px-6 py-3 m-2 mx-auto"
class: "gap-4 gap-x-2 gap-y-4"

// 尺寸
class: "w-full h-64 max-w-4xl min-h-screen"
class: "w-10 h-10 rounded-full"

// 排版
class: "text-sm text-lg font-bold text-center"
class: "truncate leading-relaxed tracking-wide"

// 颜色
class: "bg-blue-500 text-white border-gray-200"
class: "hover:bg-blue-600 dark:bg-gray-800"

// 响应式
class: "hidden lg:block"
class: "text-base md:text-lg lg:text-xl"

// 状态
class: "hover:scale-105 active:scale-95 transition-all"
class: "focus:outline-none focus:ring-2"

3.3 动态类名

let variant = use_signal(|| "primary".to_string());

let btn_class = use_memo(move || {
    let base = "px-4 py-2 rounded-lg font-medium transition-all";
    match variant().as_str() {
        "primary" => format!("{base} bg-blue-500 text-white hover:bg-blue-600"),
        "danger" => format!("{base} bg-red-500 text-white hover:bg-red-600"),
        "ghost" => format!("{base} bg-transparent hover:bg-gray-100"),
        _ => format!("{base} bg-gray-200 text-gray-700"),
    }
});

rsx! {
    button { class: "{btn_class}", "按钮" }
}

4. CSS 变量主题系统

4.1 定义变量

:root {
    --bg: #eff1f5;
    --card: #e6e9ef;
    --border: #ccd0da;
    --text: #4c4f69;
    --primary: #1e66f5;
    --hover: #ccd0da;
}

[data-theme="dark"] {
    --bg: #1e1e2e;
    --card: #181825;
    --border: #313244;
    --text: #cdd6f4;
    --primary: #89b4fa;
    --hover: #313244;
}

4.2 在组件中使用

rsx! {
    div {
        class: "rounded-lg border p-5",
        style: "
            background: var(--card);
            border-color: var(--border);
            color: var(--text);
        ",
        h3 { class: "font-semibold mb-3",
            style: "color: var(--secondary);",
            "标题"
        }
        p { style: "color: var(--tertiary);", "内容" }
    }
}

这样分工清晰: Tailwind 管布局和间距,CSS 变量管颜色。

5. 响应式布局

5.1 Tailwind 断点

| 断点 | 最小宽度 | 适用 | |------|---------|------| | 默认 | 0 | 手机 | | sm: | 640px | 大屏手机 | | md: | 768px | 平板 | | lg: | 1024px | 笔记本 | | xl: | 1280px | 桌面 |

5.2 响应式三栏

div { class: "lg:grid lg:grid-cols-[220px_1fr_240px] lg:gap-8",
    aside { class: "hidden lg:block",
        // 左侧栏:仅桌面显示
    }
    main { class: "min-w-0",
        // 主内容:始终显示
    }
    aside { class: "hidden lg:block",
        // 右侧栏:仅桌面显示
    }
}

5.3 响应式网格

rsx! {
    div { class: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6",
        for article in &articles {
            ArticleCard { summary: article.clone() }
        }
    }
}

6. 常用卡片样式组件

#[component]
fn Card(
    title: String,
    children: Element,
) -> Element {
    rsx! {
        div {
            class: "rounded-lg border p-5",
            style: "background: var(--card); border-color: var(--border);",
            h3 { class: "font-semibold mb-3 text-sm tracking-wide",
                style: "color: var(--secondary);",
                "{title}"
            }
            {children}
        }
    }
}

7. 过渡与交互动效

// 悬停效果
class: "transition-all duration-200 hover:scale-105 hover:shadow-lg"

// 显隐过渡
class: "transition-opacity duration-300 {if visible() { \"opacity-100\" } else { \"opacity-0\" }}"

// 展开折叠
class: "transition-all duration-300 overflow-hidden"
style: "
    max-height: {if expanded() { \"500px\" } else { \"0\" }};
    opacity: {if expanded() { \"1\" } else { \"0\" }};
"

8. 小结

  • 动态样式用内联 style + Signal,静态样式用 Tailwind class
  • Tailwind CDN 适合开发,生产推荐编译方式
  • CSS 变量 + data-theme 是实现暗夜模式的最佳方案
  • Tailwind 断点实现响应式布局
  • 过渡类 transition-* 实现简单动画
  • 下一章将学习表单处理与用户输入
dioxuscsstailwindstylingresponsive