lit*_*hxe 1 themes ruby-on-rails sass
我想为浅色主题使用一组 SASS 变量,并为我的深色主题更改相同的 SASS 变量。我真的不希望我的 CSS 充满每个主题的 mixins 和 if 语句,这似乎是我迄今为止找到的大部分答案。我的 CSS 几乎已经完全写好了,所以如果可能的话,我也不想回去进行大量更改。
我还想让我的用户能够选择他们想要的主题并保存他们的偏好。
我找到了一个似乎运行良好的解决方案。我可以看到,如果您有一堆非常大的主题,则此方法可能不实用,因为它会预编译每个主题。然而,我发现这对于我的项目来说是一个很好的解决方案。如果有人发现任何潜在的问题,我很乐意听到他们的声音,因为我对其中的一些还是有点陌生,并且不想违反 Rails 规则......
我的样式表文件夹看起来像这样:
app/assets/stylesheets/
_forms.scss
_layout.scss
_manifest.scss
_mixins.scss
_tables.scss
_utilities.scss
light_theme.scss
dark_theme.scss
我将所有组件分成部分以便组织。“_manifest.scss”文件导入我的主题的所有组件。
应用程序/资产/样式表/_manifest.scss
// ---------------- Import all CSS components ----------------
@import 'bootstrap';
@import 'utilities';
@import 'layout';
@import 'tables';
@import 'forms';
Run Code Online (Sandbox Code Playgroud)
我为每个主题创建一个 .scss 文件,其颜色变量位于顶部,然后导入清单。请注意,使用相同的变量名称,以便轻松替换。
应用程序/资产/样式表/light_theme.scss
// ---------------- LIGHT THEME ----------------
// Theme Colors
$light: #f4f3ef;
$medium: #9a9a9a;
$dark: #252422;
$ocean: #36414f;
$accent: cadetblue;
$red: #ed4033;
$orange: #ff8c65;
$yellow: #f4ba58;
$green: #76c29d;
$blue: #65b4c6;
// Import all components
@import 'manifest';
Run Code Online (Sandbox Code Playgroud)
应用程序/资产/样式表/dark_theme.scss
// ---------------- DARK THEME ----------------
// Theme Colors
$light: #d5d6fa;
$medium: #9e9ed6;
$dark: #0d1118;
$ocean: #1f2c44;
$accent: #806df3;
$red: #f24e77;
$orange: #f2a23b;
$yellow: #f2c54a;
$green: #34d07e;
$blue: #2c8fef;
// Import all components
@import 'manifest';
Run Code Online (Sandbox Code Playgroud)
我在 CSS 框架中使用 bootstrap,因此大部分颜色特定的 css 是通过“btn-blue”“text-orange”等类设置的。这样,当我想切换主题时,需要筛选和更改的代码就更少了。文本橙色仍然是橙色,只是深色主题上的橙色更亮,而浅色主题上的橙色更柔和,这就是为什么简单的变量交换如此必要。
有些元素需要特别指出,所以我也为每个主题使用一个主体类。这使您可以进行特定于主题的更改。
应用程序/资产/样式表/_layout.scss
body.light_theme {
background-color: $light;
color: $dark;
}
body.dark_theme {
background-color: $lake;
color: $white;
}
Run Code Online (Sandbox Code Playgroud)
接下来我希望我的用户能够设置自己的主题。我创建了一个迁移,将一列添加到我的用户表中:
class AddThemeToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :user_theme, :string
end
end
Run Code Online (Sandbox Code Playgroud)
在我的用户表单上,他们可以通过下拉菜单选择他们的主题。您的选择选项在这里很重要,因为名称会变成变量,因此请保持命名一致。
应用程序/视图/用户/_form.html.erb
<div class="form-group">
<%= form.label :user_theme, 'Theme' %>
<%= form.select :user_theme, ['Light Theme', 'Dark Theme'], class: 'form-control' %>
</div>
Run Code Online (Sandbox Code Playgroud)
现在我在应用程序控制器中设置我的主题。如果用户登录,它将采用他们的主题设置,否则默认为浅色主题。如果您要将 user_theme 行添加到现有用户表中,请确保在添加以下内容之前运行迁移来为每个用户设置默认主题,否则您将收到错误,因为该单元格为空。或者添加一些代码来检查 current_user.user_theme 是否为空,然后默认为另一个主题。(可能更好...)
application_controller.rb
class ApplicationController < ActionController::Base
before_action :set_theme
private
def set_theme
if current_user
@user_theme = current_user.user_theme.parameterize.underscore
else
@user_theme = 'light_theme'
end
end
end
Run Code Online (Sandbox Code Playgroud)
在布局文件中,我将主题作为类添加到主体中:
app/views/layouts/application.html.erb(布局文件)
<body class="<%= @user_theme %>">
...
</body>
Run Code Online (Sandbox Code Playgroud)
您可能会遇到另一个问题,如果您遇到资产编译错误,请将其添加到每个主题文件的config/initializers/assets.rb中。
Rails.application.config.assets.precompile += %w( dark_theme.css )
Rails.application.config.assets.precompile += %w( light_theme.css )
Run Code Online (Sandbox Code Playgroud)