Dynamic SCSS Rendering with Rails
5 June 2016
Dynamically Rendering SCSS in Rails
Recently at I came across a problem where I needed to dynamically include a stylesheet, or scss snippet depending on what kind of content I was showing. My first inclination was to use something like this:
# app/views/layouts.application.html.erb ... <%= yield :head %> # app/views/some_controller/some_view.html.erb <% content_for :head do %> <%= stylesheet_link_tag '/path_to/stylesheet.css' %> <% end %>
While this works just fine, however it doesn’t play quite as nicely when you’re using Turbolinks. While using Turbolinks, this implementation requires you to do a full page load every time you change the stylesheets included in the head. This isn’t the end of the world, but wasn’t quite the solution I was looking for.
After some more searching, I stumbled across the SASS lang documentation which included examples for rendering SCSS in rails.
With this knowledge, I was able to insert the computed CSS into my document, without the need to precompile, and without requiring a full page load.
In the end, my solution looked something like this.
# app/helpers/application.rb def render_styles_for(stylesheet) path = Rails.root.join('app', 'assets', 'stylesheets', styleseet ]) # style: :compact, tells the Sass::Engine to render the SCSS in # the minimum amount of space possible css = Sass::Engine.new(File.open(path).read, syntax: :scss, style: :compressed) content_tag('style', css.render) end # app/views/some_controller/some_view.html.erb <%= render_styles_for('new_styleshseet.scss') %> <h1>Some Content</h1> <p>And a little bit more content</p>
Now, you could even take this a bit further, and use it to render scss off of the web, or even from the database. All you need to do is pass some text to the
Sass::Engine.new method, and it will output scss for you!