首页 > 解决方案 > 如何根据rails中的用户设置动态更改tailwind-config.js

问题描述

我有一个 Rails 6 应用程序设置为使用带有 Webpacker 的Tailwind CSS,类似于它在这个 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'],
    },

在 Tailwind 中硬编码为配置的字体堆栈将变为:

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

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

标签: cssruby-on-railswebpacktailwind-csscss-variables

解决方案


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

将变量直接注入到 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>

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

然后您应该能够将您的 tailwindcss 配置更改为以下内容:

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

通过这种方式,我们定义了一个响应css variables值的动态 css 布局。它们作用的变量和结构位于相同的逻辑级别,这对应于提供给用户的实际网页。

可以从 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);

一旦更改此值,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 { ... */

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

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

这显然是完成的(例如)处理表单提交,保存新值,然后从数据库中提取新值以在页面的下一个渲染中评估css 变量

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


推荐阅读