【问题标题】:Generating dynamic CSS using templates使用模板生成动态 CSS
【发布时间】:2014-06-20 20:40:37
【问题描述】:

我想使用模板和Rails 4 中的TiltSASS 生成动态CSS。

  1. 假设我有以下css.sass 模板:

    $class_name: test
    $width: 329 
    $height: 425 
    
    .view-#{$class_name}
    
      width: #{$width}px
      height: #{$height}px
    
  2. 我需要master.css.sass.erb(我不确定格式),我将使用不同的参数尽可能多次地渲染我的模板。

  3. application.css,我会有这样的东西

    *= require master.css.sass.erb
    

每次我使用具有不同参数的模板时,我都会在我的master.css.sass.erb 文件中添加一行。我不知道如何使用Tilt 将参数传递给css.sass 模板。谁能帮忙看看这是否可行?


这是我到现在为止的:

  1. 模板test.css.sass.erb:

    $color: <%= color %>
    body
      background: #{$color} !important
    
  2. master.css.sass.erb 文件:

    <%
        require 'erb'
        config_path = File.expand_path("../test.css.sass.erb", __FILE__)
        template = Tilt.new(config_path)
        template.render(self, :color => 'yellow')
    
    %> .thisisrendered
        color: red
    

注意这两个文件在一个文件夹中。问题是只有以下 css 被重新渲染:

.thisisrendered
    color: red

【问题讨论】:

    标签: ruby ruby-on-rails-4 sass tilt


    【解决方案1】:

    回答您的问题:编译 erb 时,它只输出 包装器中包含的 ruby​​ 代码。您当前的代码可能运行良好(我不熟悉 Tilt 或直接 SASS),但您并没有告诉它将结果输出到 sass 文件。将master.css.sass.erb的第一行从&lt;%改为&lt;%=,然后就可以从那里调试了。

    话虽如此,我建议不要使用此过程。每次调用样式表时,您都会浪费资源来编译样式表。

    另一种方法是让样式表保持静态,就像在打开的示例中一样,这样它们就可以被预编译和缓存,然后使用股票 html 和 css 创建像 layouts/_conditional_styles.html.erb 这样的部分:

    <% unless @your_sanitized_style_object.nil? %>
      <style>
        body{
          background: <%= @your_sanitized_style_object.background_color.html_safe %> !important;
        }
      </style>
    <% end %>
    

    这可以通过在layouts/application.html.erb 文件中的应用程序 css 文件之后呈现来覆盖应用程序样式表,例如:

    <%= stylesheet_link_tag "application" %>
    <%= render "layouts/conditional_styles" %>
    

    要回答您关于为什么使用预编译资产使用较少资源然后覆盖它们的问题,请考虑您的示例 test.css.sass.erb

    $color: <%= color %>
    body
      background:$color !imporant
    

    假设颜色变量是红色的,这个过程会是这样的……首先,您的应用程序将使用它的 erb 编译器运行它,并为您提供一个 test.css.sass 文件,例如:

    $color: #ff0000
    body
      background:$color !important
    

    然后您的应用程序将使用其 sass 编译器再次运行代码,为您提供 test.css 文件,例如:

    body{ background:#ff0000 !important; }
    

    在所有这些之后,它将提供文件。在您的开发环境中,您不会看到太大的性能差异,因为您的应用程序默认为每个请求重建资产。当您需要在生产环境中将您的应用程序提供给 Web 时,差异就出现了。

    如果您的资产不依赖于应用程序中的变量,则可以预编译样式表。这意味着您的应用程序编译资产一次,在编译资产后您会得到一个样式表,如test-f25ab2b1286feb7cc98375sac732f7d0.css

    样式表将是相同的,但独特之处在于 rails 在预编译某些内容时在文件名末尾抛出的所有行话。该行话被称为指纹,其目的是在传入请求时告诉服务器是否有更新版本的文件。如果文件没有被修改,并且发出请求的系统已经将该文件下载到其缓存中,那么您的浏览器将使用缓存版本而不是重新下载样式表。

    现在假设您的 test.css.sass.erb 文件很大,例如 50kB。

    • 如果没有预编译,您的资源成本是:

      1. 每次请求都必须遍历该 50kB 文件 2 次才能从 erb > sass > css 编译它

      2. 必须为每个请求提供 50kB 文件。

    • 使用嵌入在布局的 html 中的条件样式覆盖的预编译资产,如我的第一个答案中所述:

      1. 您的编译成本几乎降到了零,因为样式表是预编译的,所以没有什么可做的,并且包含条件样式的 whatever.html.erb 模板已经由您的 erb 编译器编译,所以您只是添加渲染变量的工作。

      2. 您只需提供一次预编译的样式表,这意味着您可以在每次请求时节省约 50kB 的带宽,仅使用呈现的相关样式所需的字节。

    希望这会有所帮助,有关所有这些工作原理的更多信息,我建议从 Asset Pipeline Rails Guide 开始。

    【讨论】:

    • 感谢@h4pless 的分析器!那么,仅以你的方式为erbsass 预处理(我的想法)和erb 浪费资源不一样吗?为什么只有后一种方式(你的方式)预编译和cacaeable?我理解您使用 HTML 样式标签和 html.erb 文件构建动态 CSS 文件的想法,但这种技术是一种好的 Rails 设计(搞砸 css 和 html)吗?
    • 添加了第二部分来回答您的问题。
    • +1,我明白你的想法。不幸的是,我看不到如何使用它,因为在我的真实案例中,动态 CSS 规则的顶部是动态 ID。此外,我可以将我的SASS 转换为CSS,但结果将是大量的CSS 规则,难以更改和维护。无论如何,将&lt;% 更改为&lt;%= 可以解决最初的问题。谢谢。
    猜你喜欢
    • 2014-10-07
    • 2017-05-20
    • 2017-06-06
    • 2013-03-26
    • 2019-07-10
    • 2014-10-15
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多