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

How to change tailwind-config.js dynamically based on user settings in rails

我有一个 Rails 6 应用程序设置为使用 Tailwind CSS with Webpacker similarly to how it's done in this GoRails tutorial

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

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

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

使用 Tailwind 时,在 Rails 中还有更好的方法吗?似乎应该有一些方法可以从控制器使用 Javascript 来动态更改我的 tailwindcss-config.js 中的设置(Tailwind 配置文件是 explained here)。因此,该文件中的内容如下:

theme: {
    fontFamily: {
      display: ['Gilroy', 'sans-serif'],
      body: ['Graphik', 'sans-serif'],
    },

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

theme: {
    fontFamily: {
      display: DYNAMICALLY INSERTED FONT STACK,
      body: ANOTHER DYNAMICALLY INSERTED FONT STACK,
    },

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

我今天遇到了同样的问题。这对我有用。

# tailwind.config.js
theme: {
fontFamily: {
  custom: ['Gilroy', 'sans-serif']
},

并像

一样使用它
#sample.html.erb
<span class="font-custom"> Hello Tailwind! </span>

由于 tailwind 配置文件是“js”,您可以调用 ajax 数据,然后可以将其添加到配置文件数据中以使其动态化。当我们在 taiwlind config

中导入主题文件时

我感觉我们会尝试使用 'buildtime' 工具进行 'runtime' 操作

直接将变量注入 tailwindcss 配置文件意味着重建实际 css 服务于用户,将 tailwind 配置文件中的指令应用到 app/javascript/css(假设上述视频教程中使用的设置)。

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

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

this link 看来,在配置更改时触发 webpack 的重建并不简单。

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

在应用程序的 部分为您希望用户访问的设置定义 css 变量(更准确地说是 'css custom properties'),可以动态设置和更改(从 js也是)

<style>
  :root{
    --display-font: "<%= display_font_families %>";
    --body-font: "<%= body_font_families %>";
    --link-color: "<%= link_color %>";
  }
</style>

或者您可以创建 app/assets/stylesheets/root.css.erb(扩展很重要)并在 tailwind

之前将其包含在您的模板中

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

theme: {
    fontFamily: {
      display: "var(--display-font)",
      body: "var(--body-font)",
    },
    extend: {
      colors: {
        link: "var(--link-color)",
      },
    }

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

css variables 可以很容易地从 js 访问,这也是从 rails 进行干净访问的一种方法


现在假设用户想要更改 link 颜色(应用于所有 link)。

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

我们可能想要

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

document.documentElement.style
    .setProperty('--link-color', userSelectedColor);

一旦这个值被改变,tailwind 之前创建的所有 类,以及任何使用这个变量的规则,都会反映这个变化,不需要重建 css完全没有。

请注意,我们的用户不受可能值的任意子集的限制,任何可以被 css 接受的都是公平的游戏。通过给 config 参数分配一个 css 变量,我们实际上已经指示 tailwindcss 在它的所有 类 中指定它作为一个变量值,现在它通过 [=88 在我们的控制之下=] ... 我们绝对不需要(也不希望)webpack 来重建样式

为了使它更清楚,以我们的颜色示例为例,在 生成的 css 中将有 类 像这样 - 看看this link 了解自定义 tailwind 主题的工作原理

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

.text-link {
    color: var(--link-color);
}
.bg-link{
    background-color: var(--link-color);
}
/* .border-link { ... */

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

  • 并且我们需要一个保存功能(服务器 side/rails):当用户点击 'save' 时,新设置应该持久化(保存在数据库中)

这显然是完成了(例如)处理表单提交,保存新值,然后将从数据库中提取新值以在下一次呈现页面时 css variables 定值

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