Reputation: 608
I have four controllers in Rails (Pages
, Sessions
, Records
, Users
,) and each has a separate stylesheet named by default pages.css.scss
, sessions.css.scss
, and so on. All my global styling goes into application.css
.
However, my CSS from the separate stylesheets seems to overlap and shows up on the wrong pages. For example, I have a main div with different width for my Sessions controller (login page) and my Records controller (search function.) However, when I update the CSS for one of these, the new styling shows up on both pages.
What is happening, and how do I fix this?
Upvotes: 1
Views: 1283
Reputation: 76774
This is due to Sprockets & bad CSS structuring.
#app/assets/stylesheets/application.css
*= require_all
It's not CSS which will be the problem, but the way you're calling it - both in your asset pipeline and your application.
The above will be concatenating all your css into the main application.css
file. Whilst this might seem harmless, if you have conflicting CSS definitions, they'll override themselves.
The way around this is to firstly ensure you're not conflicting your CSS and you are calling only the appropriate CSS for your application.
Sprockets
To better understand a fix, you need to know about sprockets.
Sprockets compiles your assets to make them as efficient as possible.
Your assets reside in the asset pipeline, which has been created to be such that it will load the appropriate CSS for the different parts of your app -- both efficient and versatile.
The "conventional" way for Rails to do this is to encourage you to use controller centric assets and application level assets:
#app/assets/stylesheets/controller.css
#app/assets/stylesheets/application.css
This is okay if your CSS works in situ, but if it doesn't, you've got a problem (like what you're experiencing).
As such, the way to fix is to firstly ensure that you're splitting your CSS as you need, and you're coding the CSS properly (more in a second).
1. Remove all references in "application.css"
Sprockets gives you the ability to "include" other files in your main application.css
file:
#app/assets/stylesheets/application.css
*= require_all <- remove this line
This will prevent your "application.css" file having all the others compiled into it. The others will be compiled on their own, allowing you to call them separately:
2. Layout
#app/layouts/application.html.erb
<%= stylesheet_link_tag "application", controller_name %>
This will allow you to call the controller-centric assets you have with base-level application CSS.
The drawbacks to this are that you'll have to repeat a lot of your CSS, and will end up having completely different CSS for different parts of your app -- not the best.
The alternative is to make your CSS structured properly. This is much harder to achieve, but will give you much clearer results...
I have a main div with different width for my Sessions controller (login page) and my Records controller (search function.)
#app/assets/stylesheets/application.sass
.main
/* main styling */
&.search
/* search styling here */
&.results
/* results styling here */
This will allow you to call:
#app/views/layouts/application.haml
.main.search search stuff here
.main.results results stuff here
Upvotes: 4
Reputation: 1019
Typically, what I do is put classes on the body tag that match the controller and action. Then, in your stylesheets, you can wrap controller specific styles so they don't bleed into other areas of your app. Here's an example of what I'm talking about.
In your layout:
<body class="<%= params[:controller].parameterize %> <%= params[:action] %>">
In your stylesheet:
body.sessions.new {
.main {
width: 200px;
}
}
Upvotes: 1
Reputation: 2844
The idea behind having a CSS file for controller is to to create pieces of functionality completely independent between each other, not just independent regarding the ruby code. If you want to stick to it you could either have different layouts for each controller that only includes the corresponding CSS file, rails automatically tries to use a layout named as the controller and it falls back to application.html.erb if not found.
In practice, I think it is easier to disable the automatic generation of CSS files for each controller by adding config.generators.stylesheets = false
to your application.rb
config file and have your own hierarchy of CSS files. Take a look at this.
Hope that helps
EDIT
The other logical solution if you plan to stick to having separate css files is to have different class attributes on the views, e.g. all views for Users have a <div class="userPage"></div>
wrapping the content and use that on the css files to prevent overlapping.
Upvotes: 1