@tailwind base; @tailwind components; @tailwind utilities; /* 背景图居中 */ /* 背景图居中覆盖 - 支持自定义padding控制 */ .bg-flex-center { @apply flex items-center justify-center bg-center bg-no-repeat bg-contain; } /* 自定义样式 */ .crud-container { @apply max-w-7xl mx-auto p-6; } .crud-header { @apply mb-6 flex justify-between items-center; } .crud-table { @apply bg-white rounded-lg shadow-sm; } .crud-form { @apply bg-white p-6 rounded-lg shadow-sm; } /* 九宫格(9-slice)图片边框 Utility 目标: - 传入一张九宫格图片的 URL,保持4个角按上下左右的参数不拉伸 - 中间和4个角中间的区域拉伸 - 支持自定义重复模式、填充行为、边框扩展等高级选项 核心参数: - 图片URL:--nine-src - 切片参数:--nine-top/right/bottom/left(基于图片实际像素) - 快速设置:--nine-all(一次性设置四个角相等) - 重复模式:--nine-repeat(stretch/repeat/round/space) - 填充控制:--nine-fill(1 填充/0 不填充) - 边框扩展:--nine-outset(向外扩展距离) - 边框宽度:--nine-width(边框图像宽度) 使用说明(Tailwind 原子类 + CSS 变量): 1) 在元素上添加基础类:`nine-slice` 2) 通过 Tailwind 任意值设置 CSS 变量: - 设置图片 URL:`[--nine-src:url('/public/images/frame-9.png')]` - 设置切片大小:`[--nine-top:10] [--nine-right:10] [--nine-bottom:10] [--nine-left:10]` - 快速设置(四个角相等):`[--nine-all:15]`(等效于设置四个角都为15) - 可选高级参数: - 重复模式:`[--nine-repeat:repeat]`(默认 stretch) - 向外扩展:`[--nine-outset:5]`(默认 0) - 边框宽度:`[--nine-width:2]`(默认 1) 3) 填充控制: - 默认:填充中心区域 - 添加 `nine-slice-no-fill` 类:不填充中心,露出背景 示例:
内容区域
快速设置 - 四个角都是15px
重复图案边框
不填充中心
关键点: - 使用 CSS border-image 实现精确的9宫格切片 - 4个角保持不拉伸,边缘和中心区域可配置拉伸或重复 - 支持 fill/unfill 控制中心区域填充 - 兼容所有现代浏览器 */ @layer utilities { .H2 { @apply text-2xl font-bold; } .H3 { @apply text-xl font-bold; } .H4 { @apply text-base font-light; } .frame1 { @apply nine-slice [--nine-src:url('/public/images/Frame1.png')] [--nine-all:10] [--nine-fill:1]; } .frame-border2 { @apply absolute inset-0 nine-slice [--nine-src:url('/public/images/frame-border2.png')] [--nine-all:50] [--nine-fill:1]; } /* 九宫格边框类 - 支持基础到高级功能 */ .nine-slice { border-style: solid; width: 100%; height: 100%; /* 边框厚度:基于独立的切片值或快速设置 */ border-width: calc(var(--nine-top, var(--nine-all, 24)) * 1px) calc(var(--nine-right, var(--nine-all, 24)) * 1px) calc(var(--nine-bottom, var(--nine-all, 24)) * 1px) calc(var(--nine-left, var(--nine-all, 24)) * 1px); /* 边框图像 */ border-image-source: var(--nine-src); /* 边框图像宽度 */ border-image-width: var(--nine-width, 1); /* 边框图像向外扩展 */ border-image-outset: calc(var(--nine-outset, 0) * 1px); /* 重复模式 - 支持 stretch, repeat, round, space */ border-image-repeat: var(--nine-repeat, stretch); /* 默认切片设置(填充中心) */ border-image-slice: var(--nine-top, var(--nine-all, 24)) var(--nine-right, var(--nine-all, 24)) var(--nine-bottom, var(--nine-all, 24)) var(--nine-left, var(--nine-all, 24)) fill; } /* 不填充中心的变体 */ .nine-slice.nine-slice-no-fill { border-image-slice: var(--nine-top, var(--nine-all, 24)) var(--nine-right, var(--nine-all, 24)) var(--nine-bottom, var(--nine-all, 24)) var(--nine-left, var(--nine-all, 24)); } /* 动画支持 - 平滑过渡 */ .nine-slice-animated { transition: border-image-source 0.3s ease, border-width 0.3s ease, border-image-slice 0.3s ease; } } /* 大屏看板专用 TailwindCSS Utilities 设计目标: - 适配4K大屏分辨率 (3840x2160) - 支持多种布局模式(网格、弹性、绝对定位) - 提供专业的数据可视化容器 - 优化文字可读性和对比度 - 支持动态主题切换 */ @layer utilities { /* 大屏布局容器 */ .dashboard-container { @apply w-full h-screen overflow-hidden bg-slate-900 text-white; } .dashboard-grid { @apply grid gap-4 p-6 h-full; } .dashboard-grid-2x2 { @apply grid grid-cols-2 grid-rows-2 gap-6 p-8; } .dashboard-grid-3x3 { @apply grid grid-cols-3 grid-rows-3 gap-4 p-6; } .dashboard-grid-4x4 { @apply grid grid-cols-4 grid-rows-4 gap-3 p-4; } /* 大屏卡片容器 */ .dashboard-card { @apply bg-slate-800/80 backdrop-blur-sm rounded-xl border border-slate-700 p-6 shadow-2xl; } .dashboard-card-highlight { @apply dashboard-card border-blue-500/50 bg-slate-800/90; } .dashboard-card-warning { @apply dashboard-card border-amber-500/50 bg-orange-900/20; } .dashboard-card-danger { @apply dashboard-card border-red-500/50 bg-red-900/20; } /* 大屏标题文字 */ .dashboard-title { @apply text-4xl font-bold text-white tracking-wide mb-4; } .dashboard-subtitle { @apply text-2xl font-semibold text-slate-300 mb-3; } .dashboard-metric-title { @apply text-lg font-medium text-slate-400 mb-2; } /* 大屏数值显示 */ .dashboard-metric-large { @apply text-6xl font-bold text-white tabular-nums; } .dashboard-metric-medium { @apply text-5xl font-semibold text-white tabular-nums; } .dashboard-metric-small { @apply text-3xl font-medium text-slate-200 tabular-nums; } .dashboard-metric-trend-up { @apply text-green-400 text-2xl font-semibold; } .dashboard-metric-trend-down { @apply text-red-400 text-2xl font-semibold; } /* 图表容器 */ .chart-container { @apply w-full h-80 bg-slate-800/50 rounded-lg p-4 border border-slate-700; } .chart-container-large { @apply w-full h-96 bg-slate-800/50 rounded-lg p-4 border border-slate-700; } .chart-container-small { @apply w-full h-48 bg-slate-800/50 rounded-lg p-3 border border-slate-700; } /* 进度条 */ .dashboard-progress { @apply w-full h-3 bg-slate-700 rounded-full overflow-hidden; } .dashboard-progress-bar { @apply h-full bg-gradient-to-r from-blue-500 to-cyan-400 rounded-full transition-all duration-500; } .dashboard-progress-bar-success { @apply bg-gradient-to-r from-green-500 to-emerald-400; } .dashboard-progress-bar-warning { @apply bg-gradient-to-r from-amber-500 to-yellow-400; } .dashboard-progress-bar-danger { @apply bg-gradient-to-r from-red-500 to-rose-400; } /* 状态指示器 */ .status-indicator { @apply inline-flex items-center px-3 py-1 rounded-full text-sm font-medium; } .status-online { @apply status-indicator bg-green-500/20 text-green-300 border border-green-500/30; } .status-offline { @apply status-indicator bg-red-500/20 text-red-300 border border-red-500/30; } .status-warning { @apply status-indicator bg-amber-500/20 text-amber-300 border border-amber-500/30; } .status-dot { @apply w-3 h-3 rounded-full mr-2; } .status-dot-online { @apply status-dot bg-green-400 animate-pulse; } .status-dot-offline { @apply status-dot bg-red-400; } .status-dot-warning { @apply status-dot bg-amber-400; } /* 动画效果 */ .dashboard-fade-in { @apply animate-fade-in duration-1000; } .dashboard-slide-up { @apply animate-slide-up duration-700; } .dashboard-scale-in { @apply animate-scale-in duration-500; } /* 自定义动画 */ @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @keyframes slide-up { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } @keyframes scale-in { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } .animate-fade-in { animation: fade-in ease-out; } .animate-slide-up { animation: slide-up ease-out; } .animate-scale-in { animation: scale-in ease-out; } /* 数据表格样式 */ .dashboard-table { @apply w-full border-collapse bg-slate-800/50 rounded-lg overflow-hidden; } .dashboard-table th { @apply px-6 py-4 text-left text-sm font-semibold text-slate-300 border-b border-slate-700 bg-slate-800/80; } .dashboard-table td { @apply px-6 py-4 text-sm text-slate-200 border-b border-slate-700/50; } .dashboard-table tr:hover { @apply bg-slate-700/30; } /* 滚动条样式 */ .dashboard-scrollbar { overflow: auto; scrollbar-width: thin; scrollbar-color: #475569 #1e293b; } .dashboard-scrollbar::-webkit-scrollbar { width: 8px; height: 8px; } .dashboard-scrollbar::-webkit-scrollbar-track { background: #1e293b; border-radius: 4px; } .dashboard-scrollbar::-webkit-scrollbar-thumb { background: #475569; border-radius: 4px; } .dashboard-scrollbar::-webkit-scrollbar-thumb:hover { background: #64748b; } /* 全屏模式 */ .dashboard-fullscreen { @apply fixed inset-0 z-50 bg-slate-900; } /* 分屏布局 */ .dashboard-split-horizontal { @apply grid grid-cols-2 gap-0 h-full; } .dashboard-split-vertical { @apply grid grid-rows-2 gap-0 h-full; } /* 边缘对齐 */ .dashboard-align-top { @apply flex items-start justify-center; } .dashboard-align-bottom { @apply flex items-end justify-center; } .dashboard-align-left { @apply flex items-center justify-start; } .dashboard-align-right { @apply flex items-center justify-end; } /* 页面过渡动画 - 淡入淡出效果 */ .page-transition { @apply transition-all duration-1000 ease-out; } .page-enter { @apply opacity-0 scale-95; } .page-enter-active { @apply transition-all duration-1000 ease-out; } .page-enter-to { @apply opacity-100 scale-100; } .page-leave { @apply opacity-100 scale-100; } .page-leave-active { @apply transition-all duration-500 ease-in; } .page-leave-to { @apply opacity-0 scale-95; } /* 元素淡入动画 */ .fade-in { animation: fade-in 1s ease-out forwards; opacity: 0; /* 初始状态设为透明,避免闪烁 */ } .fade-in-left { animation: fade-in-left 1s ease-out forwards; opacity: 0; /* 初始状态设为透明,避免闪烁 */ } .fade-in-right { animation: fade-in-right 1s ease-out forwards; opacity: 0; /* 初始状态设为透明,避免闪烁 */ } .fade-in-up { animation: fade-in-up 1s ease-out forwards; } .fade-in-down { animation: fade-in-down 1s ease-out forwards; } /* 淡入动画关键帧 */ @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @keyframes fade-in-left { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } @keyframes fade-in-right { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } @keyframes fade-in-up { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fade-in-down { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } /* 动画延迟工具类 */ .delay-100 { animation-delay: 100ms; } .delay-200 { animation-delay: 200ms; } .delay-300 { animation-delay: 300ms; } .delay-400 { animation-delay: 400ms; } .delay-500 { animation-delay: 500ms; } .delay-600 { animation-delay: 600ms; } .delay-700 { animation-delay: 700ms; } .delay-800 { animation-delay: 800ms; } .delay-900 { animation-delay: 900ms; } .delay-1000 { animation-delay: 1000ms; } }