by Christina B Castro

Rails is mucking up my CSS – Already!

Or is it Ruby? I’m not really sure. I’ve been building the sample app in Chapter 2 of this Ruby Tutorial, and straight away I can see that my CSS is getting structured incorrectly for long term maintainability.

I used rails to generate the User automatically…

rails generate scaffold User name:string email:string

And Microposts…

rails generate scaffold Micropost content:string user_id:integer

I did not order these stylesheets

I took a look inside /app/assets/stylesheets/, mainly because I wanted to spend a bit of time in a part of the app that was likely to look more familiar to a front-end developer. ;)

What I found surprised me. There were already four stylesheets – none of which I would have created were I rolling a brand new app by hand.

application.css
microposts.css.scss
scaffolds.css.scss
users.css.scss

Erm, weird. Our CSS architecture should certainly not match our back-end architecture if we want it to scale. It seems like rails creates a new stylesheet every time I make a new model (and some other times too, because scaffolds aren’t a model).

How could Rails handle CSS better?

As a first pass, it seems like it would make sense for rails to add command line options to add CSS components. So you could ask rails to add buttons and it would create sass files for buttons, add .erb templates, etc. Maybe they could even be dependencies? I’ve been thinking that it would be cool to add components like buttons, boxes, grids and media blocks to NPM so that a project could require buttons and automatically get any code required for them without including an entire front end library. Maybe rails needs something similar.

Is that nuts? What do you think? Has your CSS stayed maintainable on Rails projects? I’d also love to hear about it if I’m misunderstanding aspects of Ruby, Rails, or the line between the two.

Photo credit: Christina B Castro

17 thoughts on “Rails is mucking up my CSS – Already!”

  1. it creates these files, yes — but you decide which ones you actually pull into your application in your application.css.scss file. there is sprockets syntax at the top (the *= require_self
    *= require_tree .) etc. but i always get rid of that, and use straight sass/compass imports as i’m not a big fan of sprockets (last time i looked require_tree didn’t allow you to specify the import order, not sure if still true).

  2. Can use the –assets false option so the files aren’t created. The scaffold.css still will be created though, as some of the scaffold features depend on it in a way. When you start getting more experienced, you’ll find you use scaffold less, and rely on the other generators more. The –assets false option then is generally used with the controller generator:

    bundle exec rails g controller home index –assets false

  3. I’m new at ruby as well, but here are some thoughts…

    1) The scaffolds file is new to me (I’m using rails 3.2.13, not sure if that makes a difference).

    2) In production, I think all the scss files are bundled into a single, minified, cached request to help with scaling.

    3) There may be options to tell generate (or rather the specific scaffold?) to not create .scss files. If not, maybe there are better scaffolds. Also, I’ve heard a lot of rails developers don’t use generate at all. I still use it, and still keep the one scss file per model + application + some others for different widgets (specific button types)?

  4. I usually toss the generated CSS & JS files, though the scaffold one is helpful for learning Rails.

    I actually love Rails’ asset pipeline, because you can do whatever you want there. There are a handful of gotchas, but one you realize you can put stuff anywhere, include it only when you want it, and get all the benefits of scss, etc. for free (and only if you want them), it is a great world to live in.

  5. I agree, for your same reason — the front end should be structured completely differently from the back end.

    I delete the extra css and js immediately after creating a scaffold.

    Note: you do need application.css. That handles the asset compilation. But you’ll notice there are no styles in there.

    I’m mostly a backend/js developer, but I do a bit of css, too. I find it difficult to keep the css organized as a project grows no matter what I do. I just try to refactor enough that the names don’t get too misleading. scss has helped A LOT because you can nest classes. So, I have two kinds of scss files: the page level, that are bracketed with

    .this-page {
    // styles that only show up on this-page
    }

    and component-based, that are bracketed with:

    .my-widget {
    // styles that are only used on my-widget
    }

  6. Hi again Nicole! I’m excited you’re learning Rails, I think you’re going to enjoy it. Rails has always had a bit of a love/hate relationship with the front-end IMO. The upside is that it has consistently improved over the years, even if it’s been a two steps forward, one step back, type journey.

    The scaffold generator does have command line options to control the generation of the stylesheets and other assets. You can view the documented options by running “rails generate scaffold –help”. Relevant options include:

    -y, [--stylesheets] # Generate Stylesheets
    -se, [--stylesheet-engine=STYLESHEET_ENGINE] # Engine for Stylesheets
    # Default: scss
    [--assets] # Indicates when to generate assets
    -j, [--javascripts] # Generate JavaScripts
    # Default: true
    -je, [--javascript-engine=JAVASCRIPT_ENGINE] # Engine for JavaScripts
    # Default: coffee

    The longer options have undocumented –no-* options, like “–no-stylesheets”.

    You can change the default generator options for your application in your application.rb file. If you set stylesheets to false then the default will be to skip generating the empty stylesheets. I rarely use the generators anymore, but when I do I set both stylesheets and assets to false. More information is available in the Generators Guide. http://guides.rubyonrails.org/generators.html#customizing-your-workflow

  7. First, the generated CSS structure is all about Rails, and doesn’t have anything to do with Ruby itself. The boundary between the two can be confusing at first, especially when learning Ruby via Rails, but a rough guideline is that Ruby is the underlying general purpose programming language, and knows practically nothing about the web technologies. The Rails framework, written in Ruby, provides all those parts.

    Rails has its own idea of the CSS files and structure which it generates when you use scaffolding, as you’ve seen. Scaffolding itself is certainly useful in some situations, e.g. quick explorations of ideas, where you don’t care so much about the details and appearance but want to get a feature up and running fast. But when you progress, you’re unlikely to want to use all of the defaults scaffolding gives you. I think the (imho excellent) tutorial you’re reading does a good job illustrating this by showing the scaffolding version in the early chapters and then building the same (and more) in a more manual, piece by piece fashion in the later chapters.

    Furthermore, even when you are using scaffolding to generate some boilerplate to start with, you don’t have to keep all the default generated files. There’s nothing magical about most of them, and you can delete or overwrite the ones you don’t need/want. Of course you’ll need an understanding of what the files are used for, and which ones may be required to exist, but you’ll build that knowledge when learning more. E.g. with the CSS files, you can get rid of the generated ones and create your own structure – except for application.css, which has a special purpose.

    The idea about using Rails to add/generate more specific CSS components goes in a sense much further and deeper, and I’m not well-enough aware of the current status in that area to comment in depth, but at least at first sight it seems this would probably be best explored via a separate gem (i.e. a Rails extension/plugin). Authoring such an extension from scratch is a way more advanced topic, but if someone has already made one, taking it into use would be much simpler.

  8. I’m a front-ender but also learning Rails so I can make my own apps. I’ve struggled to make it past the first few models and views so have yet to dive into the joys of how it thinks I should structure my CSS yet.

    I tend to prefer creating a library of components and including and extending them where necessary rather than having a separate stylesheet for every page or interaction.

    I have a feeling that Rails won’t mind too much if you curated your CSS a bit more by hand but it would no doubt continue to create all the cruft automatically when using generators. One bit of advice I have heard in my brief journey into Rails is not to use the `scaffold` command — maybe that’s the start of the solution?

  9. The scaffold command isn’t really meant to be used when you get past the beginner/learning stage. It creates lots of stuff with little thought to optimization/efficiency. Though, if you read up a little more on Rails and CSS you’ll see how Rails is actually handling these css files. Rails creates a manifest file ‘application.css’ that causes a single css file to be generated at run time. So you can make multiple css files for organizational purposes in your development environment with the assurance that only one file is being read at runtime.

    Clay

  10. You’re not misunderstanding Rails, but you’ve missed an important point:

    Rails’ `scaffold` generator automatically creates a `resource_name`.css.scss stylesheet, which is why you see those files with names matching those of your Models. Only the `scaffold` and `controller` generators do this.

    The file `application.css.scss` is the only one included by default, and is the one where you include all your other stylesheets. This means you can order (and name) your stylesheets any way you see fit – you don’t even have to type them in manually; you can include entire directories with Sprockets (the engine that handles all of this for you in Rails).

    Hope it helps! (and thanks for introducing me to OOCSS, which helped me tame a very, very large Rails app!)

  11. I stay away from scaffolds, creating the files I really want manually. A CSS file per model sounds crazy to me as well.

    Out of curiosity, for your investigation into Ruby, have you considered starting with a less batteries-included framework like Sinatra? I started by looking at Rails as well, but during and afterward I had the thought that it might have been easier to start with something that’s not as full of features and magic.

  12. The scaffold command is good tool for when you’re starting out with Rails because it generates so much stuff that you can look over and immediately begin playing with.

    Rails developers don’t generally run the scaffold command on “real” production projects though, opting instead for only writing the code that they need by hand (or after simply generating the models or controller file shells).

    They tend feel the same way about all the generated Ruby code that you do about the generated CSS — it’s not likely a perfect fit for their application and is probably doing too much.

    Hope that helps.

  13. I’m learning Rails at the moment, so I can’t claim to be an expert, but I gather that most Rails developers avoid using the scaffolding in real life, which means that you can write your own stylesheets and have more control over your project.

    Happily, the tutorial that you’re working through – unlike 99% of Rails tutorials that I’ve found so far – moves onto building a site without using scaffolding in the third or fourth chapter. (I’m much happier with Rails now that I understand exactly what each command generates.)

  14. As said, the css files can be opt-out.

    However, creating them there by default is one of the bigger reason why Rails is not my cup of tea. Especially since OOCSS and SMACSS proved most valuable and useful.

    However, take a look att application.scss to see how Sprockets works. It can deal with minification and concatination in the future, when or if Rails are just to build something that should be used in production.

  15. In the cases where I’ve worked with a Rails stack (Rails 3, admittedly), I’ve found that what I call the “boilerplate” css files generated by Rails serve as a great way for backend-focused engineers to write CSS successfully.

    “Successfully” doesn’t mean “well” or “in a way that scales well”, however. It *does* mean “in a way that makes sense to them”. And as a front-end engineer, I’ve found that very boilerplate *incredibly* frustrating to work with, similar to your experience so far.

    So the trade-off here is that fewer engineers are required to crank out a “successful” site/app, at the cost of front-end performance/scalability/ease of maintenance; one or two engineers can work on the full stack, instead of having dedicated roles. This mirrors my experience with frameworks such as Drupal.

    It’d be lovely if Rails (and others) adhered to commonly accepted front-end architectures (Express does this better, IMO). I think it’d also mean teaching the ability to switch a person’s cognitive state between “Ruby-mind”, for example, to “CSS-mind”, and back.

  16. This is true. I am learning Rails as well and sort of noticed the same thing. However, i have done basic development on the Magento platform before and if you think Rails is bad in this regard, look at the mess that Magento creates. Its absolute chaos.

    But it seems to work somehow, some of the largest ecommerce sites in the world use it, and I guess you could argue the exact same thing for rails.

  17. It’s Rails, not Ruby.

    Pretty sure nobody uses the scaffolding except to create a few on-the-fly examples and understand how it’s wired together.

    My friend was using Foundation the other day and bemoaned the fact that in his project, he needed to support IE in a way that Foundation 4 didn’t, but Foundation 3 did. So he said it’d be neat if one could simply drop in bits and pieces of such a framework as necessary, without buying into a giant monolithic framework that subsequently dominates all of your CSS decisions.

    Ruby and/or Rails and/or NPM could provide tools to “bootstrap” your CSS files in a maintainable way. TOTALLY! And that would provide a sensible proscribed course of action for developers who, bless them, code bad CSS out of ignorance of the right way to do it.

    Ignoring which language and tools you’d use, in an abstract way, what commands would you want to issue and what results/stylesheets would you get from these commands?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>