How do I use Controller specific stylesheets in Rails 3.2.1?

23,372

Solution 1

I don't think it works that way (Home.css being applied only to Home controller actions). The different files are just for separation, to make it clearer what are the CSS rules describing. You can read this guide about the asset pipeline. I'm guessing you altered the default application.css.scss and removed the line importing all CSS files from app/assets/stylesheets.

Solution 2

It can work this way and Marek is quite correct, the answer is in the guide. In the introduction to section 2.1:

For example, if you generate a ProjectsController, Rails will also add a new file at app/assets/javascripts/projects.js.coffee and another at app/assets/stylesheets/projects.css.scss. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as <%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag params[:controller] %>.

So to set your application up to load controller specific stylesheets:

First, disable the default loading of all stylesheets by removing any extra requires in the application.css manifest.

Typically you'll see an entry like this:

 *= require_tree .

If you still want to load some common css files, you can move them to a subdirectory and do something like this:

 *= require_tree ./common

Second, In your application's layout add the suggested stylesheet_link_tag eg

<%= stylesheet_link_tag    "application", :media => "all" %>
<%= stylesheet_link_tag params[:controller] %>

In this example we first load the application css file, we then load any css file that matches the current controller name.

Solution 3

I've solved this problem with a simple solution. I add to body the controller name as a class, editing views/layouts/application.html.slim:

body class=controller.controller_name

Or views/layouts/application.html.erb:

<body class="<%= controller.controller_name%>">

And then in my css I just use body.controller_name as a namespace:

/* example for /users/ */

body.users {
    color: #000;
}

body.users a {
    text-decoration: none;
}

For small projects I think it's fine.

Solution 4

TL;DR:

Ignore the comment, it's not made by Sass. But put: @import "*"; into your application.css.scss file, and it will automatically import all the controller scss files.

Full read:

Disclaimer: This is my current understanding of the asset pipeline flow with and without Sass.

I think this comment is written by the standard Rails Asset pipeline (sprockets), and not by Sass:

// Place all the styles related to the Home controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

The standard pipeline will handle scss files but doesn't presume an application.css.scss file. But if you create such a file with Sass, then Sass will compile it to the application.css file.

If you use the normal Rails asset pipeline, without Sass, then sprockets would load the css file into the application.css file automatically (if that file has the default *= require_tree . line in it).

When you use Sass, with an application.css.scss file, Sass will compile this file into a application.css file. (I assume it would overwrite or take precedence over any application.css file you already had).

To get your home.css.scss file (and other controller files) automatically included, put this line into your application.css.scss file:

@import "*";

For reference, see this question: Is it possible to import a whole directory in sass using @import?

Share:
23,372

Related videos on Youtube

Only Bolivian Here
Author by

Only Bolivian Here

Updated on July 09, 2022

Comments

  • Only Bolivian Here
    Only Bolivian Here almost 2 years

    Using Rails 3.2.1


    I created a simple controller called Home using the command:

    rails g controller Home index
    

    And it created a new controller and view for me:

    enter image description here

    Notice how there are two stylesheets, one "Application" and one "Home". I can't find any documentation to support this assumption but I'm guessing you put styles that will only be applied to the "Home" views, in the Home.css.scss file, correct?

    So as a test, I added in some global styles to Application.css.scss.erb and ran the application.

    The styles applied as expected.

    Next, I added in some rules to the Home.css.scss file and I visited a "Home/index" view, yet the style in that file wasn't attached, neither as a seperate CSS reference link, or even appended to the single Application.css.scss file. This is highly confusing to me, since the comments say:

    // Place all the styles related to the Home controller here.
    // They will automatically be included in application.css.
    // You can use Sass (SCSS) here: http://sass-lang.com/
    

    Why aren't the rules written in Home.css.scss applied to my website?

  • Only Bolivian Here
    Only Bolivian Here about 12 years
    Yes, you are correct I removed *= require_tree because it was causing a circular dependency on Sprocket. I have no idea what that means because I'm new to Rails but removing that solved the issue. Amazingly, I've added that back in just to test your answer and now it works without a hitch. :S Still very confused.
  • coderVishal
    coderVishal over 8 years
    It is also the preferred answer in the book Agile Development with Rails 4 by Sam Ruby. If your using scss simply wrap your entire code inside your controller name like .body{ /*Entire css code in here*/}