如何定制 Roundcube 的颜色 (Elastic 皮肤)

配置环境

系统: ubuntu 22.04

Roundcube: 1.6.11

PHP: 8.1

MySQL: 8.0

Apache2: 2.4.52

定制步骤

  1. 在 Roundcube 皮肤目录的 styles.less 文件**末尾**加入如下一行,以导入自定义 CSS 文件:

    @import (inline) "custom.css";

    (假设您使用的是 Elastic 皮肤,该文件通常位于 [Roundcube 根目录]/skins/elastic/styles/styles.less

  2. 在皮肤的 styles 目录(例如 elastic/styles 目录)创建 custom.css 文件,并加入以下内容。这些 CSS 代码使用了大量 !important 来确保覆盖 Roundcube 默认的 LESS 编译样式,并引入了现代化的美化效果和变量定义。

    /* Roundcube Elastic 皮肤个性化定制 */
    
    /* 主要颜色变量定义 */
    :root {
        --primary-color: #2563eb;        /* 主蓝色 */
        --primary-hover: #1d4ed8;        /* 悬停蓝色 */
        --secondary-color: #10b981;      /* 辅助绿色 */
        --accent-color: #f59e0b;         /* 强调橙色 */
        --background-light: #f8fafc;     /* 浅背景色 */
        --background-dark: #1e293b;      /* 深背景色 */
        --text-primary: #1f2937;         /* 主文字色 */
        --text-secondary: #6b7280;       /* 次要文字色 */
        --border-color: #e5e7eb;         /* 边框色 */
    }
    
    /* 顶部工具栏美化 */
    .toolbar {
        background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)) !important;
        border: none !important;
        box-shadow: 0 2px 10px rgba(0,0,0,0.1) !important;
    }
    
    .toolbar .toolbar-menu a,
    .toolbar .toolbar-menu button {
        color: white !important;
        transition: all 0.3s ease !important;
    }
    
    .toolbar .toolbar-menu a:hover,
    .toolbar .toolbar-menu button:hover {
        background-color: rgba(255,255,255,0.2) !important;
        border-radius: 6px !important;
    }
    
    /* 左侧导航栏美化 */
    .sidebar {
        background: var(--background-light) !important;
        border-right: 1px solid var(--border-color) !important;
    }
    
    .sidebar .sidebar-menu li a {
        color: var(--text-primary) !important;
        transition: all 0.3s ease !important;
        border-radius: 8px !important;
        margin: 2px 8px !important;
    }
    
    .sidebar .sidebar-menu li a:hover,
    .sidebar .sidebar-menu li.selected a {
        background: var(--primary-color) !important;
        color: white !important;
        transform: translateX(4px) !important;
    }
    
    .sidebar .sidebar-menu li a.active {
        background: linear-gradient(135deg, var(--primary-color), var(--primary-hover)) !important;
        color: white !important;
        box-shadow: 0 2px 8px rgba(37, 99, 235, 0.3) !important;
    }
    
    /* 邮件列表美化 */
    .messagelist tbody tr {
        transition: all 0.2s ease !important;
        border-bottom: 1px solid var(--border-color) !important;
    }
    
    .messagelist tbody tr:hover {
        background: linear-gradient(90deg, rgba(37, 99, 235, 0.05), rgba(16, 185, 129, 0.05)) !important;
        transform: translateX(2px) !important;
    }
    
    .messagelist tbody tr.selected {
        background: linear-gradient(90deg, rgba(37, 99, 235, 0.1), rgba(16, 185, 129, 0.1)) !important;
        border-left: 4px solid var(--primary-color) !important;
    }
    
    .messagelist tbody tr td {
        color: var(--text-primary) !important;
        padding: 12px 8px !important;
    }
    
    .messagelist tbody tr.unread td {
        font-weight: 600 !important;
        color: var(--text-primary) !important;
    }
    
    .messagelist tbody tr .subject {
        color: var(--primary-color) !important;
        font-weight: 500 !important;
    }
    
    /* 按钮美化 */
    .btn-primary,
    .button.primary {
        background: linear-gradient(135deg, var(--primary-color), var(--primary-hover)) !important;
        border: none !important;
        border-radius: 8px !important;
        color: white !important;
        transition: all 0.3s ease !important;
        box-shadow: 0 2px 8px rgba(37, 99, 235, 0.3) !important;
    }
    
    .btn-primary:hover,
    .button.primary:hover {
        transform: translateY(-2px) !important;
        box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4) !important;
    }
    
    .btn-secondary,
    .button.secondary {
        background: var(--secondary-color) !important;
        border: none !important;
        border-radius: 8px !important;
        color: white !important;
        transition: all 0.3s ease !important;
    }
    
    .btn-secondary:hover,
    .button.secondary:hover {
        background: #059669 !important;
        transform: translateY(-1px) !important;
    }
    
    /* 搜索框美化 */
    .searchbar input {
        border: 2px solid var(--border-color) !important;
        border-radius: 25px !important;
        padding: 8px 16px !important;
        transition: all 0.3s ease !important;
        background: white !important;
    }
    
    .searchbar input:focus {
        border-color: var(--primary-color) !important;
        box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1) !important;
        outline: none !important;
    }
    
    /* 邮件内容区域美化 */
    .mail-content {
        background: white !important;
        border-radius: 12px !important;
        box-shadow: 0 2px 10px rgba(0,0,0,0.05) !important;
        margin: 8px !important;
    }
    
    .mail-header {
        background: linear-gradient(135deg, rgba(37, 99, 235, 0.05), rgba(16, 185, 129, 0.05)) !important;
        border-radius: 12px 12px 0 0 !important;
        padding: 16px !important;
        border-bottom: 1px solid var(--border-color) !important;
    }
    
    /* 文件夹树美化 */
    .treelist li a {
        color: var(--text-primary) !important;
        transition: all 0.3s ease !important;
        border-radius: 6px !important;
        margin: 1px 4px !important;
    }
    
    .treelist li a:hover {
        background: rgba(37, 99, 235, 0.1) !important;
        color: var(--primary-color) !important;
        transform: translateX(4px) !important;
    }
    
    .treelist li.selected > a {
        background: var(--primary-color) !important;
        color: white !important;
        font-weight: 500 !important;
    }
    
    /* 标签和徽章美化 */
    .badge {
        background: var(--accent-color) !important;
        color: white !important;
        border-radius: 12px !important;
        font-weight: 500 !important;
        padding: 2px 8px !important;
    }
    
    /* 表单元素美化 */
    input[type="text"],
    input[type="email"],
    input[type="password"],
    textarea,
    select {
        border: 2px solid var(--border-color) !important;
        border-radius: 8px !important;
        padding: 8px 12px !important;
        transition: all 0.3s ease !important;
    }
    
    input[type="text"]:focus,
    input[type="email"]:focus,
    input[type="password"]:focus,
    textarea:focus,
    select:focus {
        border-color: var(--primary-color) !important;
        box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1) !important;
        outline: none !important;
    }
    
    /* 主布局美化 */
    body {
        background: linear-gradient(135deg, #f0f9ff, #ecfdf5) !important;
    }
    
    .content {
        border-radius: 12px !important;
        overflow: hidden !important;
        box-shadow: 0 4px 20px rgba(0,0,0,0.1) !important;
    }
    
    /* 滚动条美化 */
    ::-webkit-scrollbar {
        width: 8px !important;
    }
    
    ::-webkit-scrollbar-track {
        background: var(--background-light) !important;
    }
    
    ::-webkit-scrollbar-thumb {
        background: var(--primary-color) !important;
        border-radius: 4px !important;
    }
    
    ::-webkit-scrollbar-thumb:hover {
        background: var(--primary-hover) !important;
    }
    
    /* 右键菜单美化 */
    .popupmenu {
        border: none !important;
        border-radius: 8px !important;
        box-shadow: 0 8px 25px rgba(0,0,0,0.15) !important;
        background: white !important;
    }
    
    .popupmenu li a {
        transition: all 0.2s ease !important;
    }
    
    .popupmenu li a:hover {
        background: var(--primary-color) !important;
        color: white !important;
    }
    
    /* 状态栏美化 */
    .statusbar {
        background: linear-gradient(90deg, var(--background-light), white) !important;
        border-top: 1px solid var(--border-color) !important;
        color: var(--text-secondary) !important;
    }
    
    /* 动画效果 */
    @keyframes fadeIn {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: translateY(0); }
    }
    
    .mail-content,
    .messagelist tbody tr {
        animation: fadeIn 0.3s ease-out !important;
    }
    
    /* 响应式优化 */
    @media (max-width: 768px) {
        .sidebar {
            box-shadow: 2px 0 10px rgba(0,0,0,0.1) !important;
        }
        
        .toolbar {
            padding: 8px !important;
        }
    }
    
  3. 执行 LESS 编译命令生成新的 CSS 文件,并清除 Roundcube 缓存,然后重启 Apache2 服务。

    (注意:请确保您已安装 lessc,并且在 Roundcube 根目录下执行命令,或者指定正确的路径。www-data 是 Ubuntu/Debian 上 Apache 的默认用户。)

    sudo -u www-data lessc skins/elastic/styles/styles.less skins/elastic/styles/styles.min.css
    sudo rm -rf /var/www/roundcube/temp/*
    sudo systemctl restart apache2
  4. 最后一步: 清除浏览器缓存(硬刷新),即可看到新的 Webmail 样式。