如何根据 Rails 中的用户设置动态更改 tailwind-config.js

Lee*_*lly 9 css ruby-on-rails css-variables webpack tailwind-css

我有一个 Rails 6 应用程序设置为将Tailwind CSS与 Webpacker一起使用,这与 GoRails 教程中的做法类似。

我希望能够根据控制器和操作动态更改 Tailwind 默认值,以便用户通过选择一些选项然后动态调整一些 Tailwind 配置选项来轻松“皮肤”站点的部分。(如何使用它的一个例子是用户登录网站的管理区域,更改他们的字体系列和背景颜色以匹配他们的品牌。)

我不能仅仅根据条件将样式表添加到布局中,因为我必须覆盖我想要更改的 Tailwind css 变量的所有实例(例如“sans-serif”)。随着 Tailwind 的发展,这将需要大量工作并且难以维护。

如果有一种方法可以将用户选择的选项动态插入到 Tailwind 配置文件 ( /javascript/stylesheets/tailwindcss-config.js ) 中,那将是理想的,但我不确定如何执行此操作。

使用 Tailwind 时,是否有更好的方法在 Rails 中执行此操作?似乎应该有某种方法可以使用控制器中的 Javascript 来动态更改我的 tailwindcss-config.js 中的设置(这里解释了Tailwind 配置文件)。因此,该文件中的内容如下:

theme: {
    fontFamily: {
      display: ['Gilroy', 'sans-serif'],
      body: ['Graphik', 'sans-serif'],
    },
Run Code Online (Sandbox Code Playgroud)

在 Tailwind 中硬编码为配置的字体堆栈会变成这样:

theme: {
    fontFamily: {
      display: DYNAMICALLY INSERTED FONT STACK,
      body: ANOTHER DYNAMICALLY INSERTED FONT STACK,
    },
Run Code Online (Sandbox Code Playgroud)

你将如何在 Rails 中做到这一点?我的 Tailwind 配置文件位于 /javascript/stylesheets/tailwindcss-config.js。这可能与 Rails 中的 Webpack 有关吗?这甚至是使用 Webpacker + Tailwind 使用 Rails 6 的正确方法吗?

giu*_*ulp 20

我有一种感觉,我们会尝试使用“构建时”工具进行“运行时”操作

将变量直接注入到 tailwindcss 配置文件中将意味着重建为用户提供的实际 css,将 tailwind 配置文件中的说明应用到 app/javascript/css 中的实际内容(假设上述视频教程中使用的设置)。

操作由 webpack 进行,通过 webpacker gem 集成。

恕我直言,webpack 和 tailwind 都不是为了在运行时重建资产而设计的,而且,即使我清楚地知道一台通用机器可以做任何事情;) 我想知道走这条路会走哪条路,主要是在可维护性。

这个链接看来,在配置更改时触发 webpack 的重建并不简单。

这是一个稍微不同的尝试路径:

在应用程序的 <head> 部分为您希望用户访问的设置定义 css 变量(更准确地说是“css 自定义属性”),可以动态设置和更改(也可以从 js 中)

<style>
  :root{
    --display-font: "<%= display_font_families %>";
    --body-font: "<%= body_font_families %>";
    --link-color: "<%= link_color %>";
  }
</style>
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建 app/assets/stylesheets/root.css.erb(扩展名很重要)并在顺风之前将其包含在您的模板中

然后您应该能够将您的 tailwindcss 配置更改为如下所示:

theme: {
    fontFamily: {
      display: "var(--display-font)",
      body: "var(--body-font)",
    },
    extend: {
      colors: {
        link: "var(--link-color)",
      },
    }
Run Code Online (Sandbox Code Playgroud)

这样我们就定义了一个动态的 css 布局来响应css variables的值。变量及其作用的结构位于同一逻辑级别,对应于提供给用户的实际网页。

可以从 js 轻松访问css 变量,这也是从 Rails 进行干净访问的一种方法


现在让我们假设用户想要更改链接颜色(应用于所有链接)。

在我们想象的设置表单中,她选择了一种任意颜色(在任何 css 有效格式中——这里唯一的限制是它必须是一个有效的 css 值,你需要通过某种形式的输入验证来解决这个问题)。

我们可能想要

  • 预览功能(客户端/js):无需重新加载页面,用户应该能够临时将新设置应用于页面。这可以通过 js 调用来完成,该调用为变量--link-color设置新值
// userSelectedColor is the result of a user's choice, 
// say it's "#00FF00"

document.documentElement.style
    .setProperty('--link-color', userSelectedColor);
Run Code Online (Sandbox Code Playgroud)

一旦这个值改变了,所有之前由 tailwind 创建的类,以及任何使用这个变量的规则,都会反映这个改变,根本不需要重新构建 css。

请注意,我们的用户不受可能值的任意子集的限制,css 可以接受的任何内容都是公平的游戏。通过为 config 参数分配一个 css 变量,我们实际上已经指示 tailwindcss 在其所有类中将其指定为变量值,现在通过 css/js 由我们控制......我们绝对不需要(也不想要) webpack 重建样式

为了更清楚,使用我们的颜色示例,在生成的 css中将有这样的类 - 请查看此链接以了解自定义尾风主题的工作原理

/* GENERATED BY TAILWIND - well, this or something very similar :) */

.text-link {
    color: var(--link-color);
}
.bg-link{
    background-color: var(--link-color);
}
/* .border-link { ... */
Run Code Online (Sandbox Code Playgroud)

显然浏览器需要知道--link-color的值(我们已经在:root部分定义了它)并且值本身可以是任何有效的 css,但我们感兴趣的是它可以随时更改,自动传播使用它的每个规则的更改,它是一个css 变量......

  • 我们需要一个保存功能(服务器端/导轨):当用户点击“保存”时,新设置应该保持不变(保存在数据库中)

这很容易完成(例如)处理表单提交,保存新值,然后从数据库中提取新值以在页面的下一次呈现时对css 变量进行赋值

只是我的 2 美分 :) 玩得开心!