Ask A Question

Notifications

You’re not receiving notifications from this thread.

Dynamically create sass variables in rails

Matt Taylor asked in CSS

I have a multi-tenant app where each tenant can set their primary and accent colors. Is there a way i can grab those values and insert them into a sass file on page load? I"m using rails 5 and postgres if that helps. I have seen some articles but most are many years old.

Thanks

Reply

SASS files supposed to be compiled by Rails Assets Pipeline, and served as static assets. It depends on your project configuration, but in most common case, SASS-to-CSS compillation happens each time you update sources (in development), OR during deployment (in production). So there are no direct way to affect SASS variables from Rails app runtime. Technically it is possible, but will affect performance badly.

There are alternative options though. If I understand your request correctly, you need to alter a style for some element, according to the state on your server side. In this case it is possible to predefine multiple CSS classes, and use one of them in the view, that suits a condition:

Stylesheet:

.tenant-specific {
    .tenant-specific--tenant1 {
                color: red;
        }

    .tenant-specific--tenant2 {
                color: green;
        }
}

And the view:

<div class="tenant-specific tenant-specific--tenant<%= current_tenant_id %>">

In case you don't know beforehand, how much styles will be required, or if the color supposed to be dynamic, it is possible to use different approach. For example, you may generate some inline CSS:

<div style="color:<%= current_tenant_color %>">

Where current_tenant_color is a variable or some presenter method that returns hex color code for current tenant.

Third option is to add ERB code to your SASS file (just rename *.scss to *.scss.erb, and it will work as usual). Next example uses predefined values from Constants module to set CSS properties.

// application.sass.erb

.tenant-specific {
    .tenant-specific--tenant1 {
                color: <%= Constants::FIRST_TENANT_COLOR %>;
        }

    .tenant-specific--tenant2 {
                color: <%= Constants::SECOND_TENANT_COLOR %>;
        }
}

It is also possible to generate color code dynamically, instead of using constants, or get it in any different manner that suits you. ERB code within *.sass.erb files will behave pretty much like ordinary ERB code in Rails views. The only difference is that it will be executed during SASS compillation, but not each time Rails action fires.

Reply

Thanks a lot for your response. I ended up going with just the inline styles since it was only a few elements that need to be dynamic. I did try to do the sass.erb but it didn't seem to have the same scope(current_account||current_user) and that makes sense now that you mention the sass file will not be updated on every action, and those variables wouldn't make sense to use.

Thanks

Reply

Inline styles are not ideal, you could always create a class, and reference it in the header in a style tag. Then inject the colours into that?

<style>
.custom_class_1 { color: colour here; }
.custom_class_2 { color: colour here; }
</style>

then maybe set the colour in the application controller and cache it somehow?

Reply

What about .erb syntax? Can't pass: <%= content_tag :div, style: "--rating: <%= rating_value %>" %>
Thanx!

Reply

You can pass the variable in, you’d need to create a css class for that particular element. For example on a flash, you would have success and error Classes, and pass that class into the .erb

Reply

Backtalk factors are utilized to store data that can be reused all through the template when you really want. You can store things like tones, textual style stacks, or any CSS esteem as per your future reusability. The $ image is utilized to make something a variable.

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 87,563+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.