I occasionally have to add a class to an html element based on a condition. The problem is I can't figure out a clean way of doing it. Here's an example of the stuff I've tried:
<div <%= if @status = 'success'; "class='ok'"; end %>>
some message here
</div>
OR
<% if @status == 'success' %>
<div class='success'>
<% else %>
<div>
<% end %>
some message here
</div>
I don't like the first approach because it's crowded looking and hard to read. I don't like the second approach because the nesting is screwed up. It'd be nice to put it in the model, (something like @status.css_class
), but that doesn't belong there. What do most people do?
Avoiding logic in the views
The problem with the standard approach is that it requires logic in the form of
if
statements or ternaries in the view. If you have multiple conditional CSS classes mixed with default classes, then you need to put that logic into a string interpolation or ERB tag.Here's an updated approach that avoids putting any logic into the views:
class_string
methodThe
class_string
helper takes a hash with key/value pairs consisting of CSS class name strings and boolean values. The result of the method is a string of classes where the boolean value evaluated to true.Sample Usage
Other Use Cases
This helper can be used within
ERB
tags or with Rails helpers such aslink_to
.Either/Or Classes
For use cases where a ternary would be necessary (e.g.
@success ? 'good' : 'bad'
), pass an array where the first element is the class fortrue
and the other is forfalse
Inspired by React
This technique is inspired by an add-on called
classNames
(formerly known asclassSet
) from Facebook’sReact
front-end framework.Using in your Rails projects
As of now, the
class_names
function does not exist in Rails, but this article shows you how to add or implement it into your projects.I use the first way, but with a slightly more succinct syntax:
Though usually you should represent success with boolean
true
or a numeric record ID, and failure with booleanfalse
ornil
. This way you can just test your variable:A second form using the ternary
?:
operator is useful if you want to choose between two classes:Finally, you can use Rail's record tag helpers such as
div_for
, which will automagically set your ID and class based on the record you give it. Given aPerson
with id 47:You can also use the content_for helper, especially if the DOM is located in a layout and you want to set the css class depending on the partial loaded.
On the layout:
On the partial:
That is it.