Using Rails 3.1 assets pipeline to conditionally use certain css
I've discovered a way to make it less rigid and future proof by still using the asset pipeline but having the stylesheets grouped. It's not much simpler than your solution, but this solution allows you to automatically add new stylesheets without having to re-edit the whole structure again.
What you want to do is use separate manifest files to break things up. First you have to re-organize your app/assets/stylesheets
folder:
app/assets/stylesheets
+-- all
+-- your_base_stylesheet.css
+-- print
+-- blueprint
+-- print.css
+-- your_print_stylesheet.css
+-- ie
+-- blueprint
+ ie.css
+-- your_ie_hacks.css
+-- application-all.css
+-- application-print.css
+-- application-ie.css
Then you edit the three manifest files:
/**
* application-all.css
*
*= require_self
*= require_tree ./all
*/
/**
* application-print.css
*
*= require_self
*= require_tree ./print
*/
/**
* application-ie.css
*
*= require_self
*= require_tree ./ie
*/
Next you update your application layout file:
<%= stylesheet_link_tag "application-all", :media => "all" %>
<%= stylesheet_link_tag "application-print", :media => "print" %>
<!--[if lte IE 8]>
<%= stylesheet_link_tag "application-ie", :media => "all" %>
<![endif]-->
Lastly, don't forget to include these new manifest files in your config/environments/production.rb:
config.assets.precompile += %w( application-all.css application-print.css application-ie.css )
Update:
As Max pointed out, if you follow this structure you have to be mindful of image references. You have a few choices:
- Move the images to follow the same pattern
- Note that this only works if the images are not all shared
- I expect this will be a non-starter for most since it complicates things too much
- Qualify the image path:
background: url('/assets/image.png');
- Use the SASS helper:
background: image-url('image.png');
How do you properly include a conditional css file for IE in Rails 3.1+ (asset pipeline) and haml?
/[if IE]
= stylesheet_link_tag 'ie'
Rails Asset Pipeline with conditional CSS files
i have a project with similar requirements and i use the techniques shown in the linked answer:
# app/views/layouts/application.html.haml
= stylesheet_link_tag "application", "labels/#{Whitelabel[:label_id]}"
# config/application.rb
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
config.assets.precompile += %w( active_admin.js active_admin.css labels/* )
this includes an additional stylesheet, that is not included in the application.rb
have a look at the full source: https://github.com/phoet/on_ruby/
Rails Precompiling Assets - Best Practice for responsive css
I think you are taking a wrong direction for using the asset-pipeline in general . If you are about to use the pipeline , you just have to keep the application.css
- this is a manifest file , that you use to include your css
files . My advice is to move your link href=
from view and use the manifest file (application.css) like this :
*= require_self
*= require foundation
*= require mobile_size
....
*= require_tree
What you are including now are precompiled css files (notice the hash prefixes) and every time you modify your assets , the hash prefix will change .
The same is the situation with .js
files - you have to include them in application.js
manifest file .
EDIT : The idea of using SASS (3.2) and media-queries (as described in this CSS-tricks article, regards to @penner) would fit nicely in this case.
Adding page-specific CSS to Rails Asset Pipeline
I found this blog post to be very helpful: http://blog.seancarpenter.net/2012/11/05/page-specific-javascript-with-the-asset-pipeline/. My answer paraphrases what this blogger already wrote and fills in a few missing details.
First, it's important that you've read and understood the Rails Guide to the Asset Pipeline. Unfortunately, this guide doesn't clearly explain how to add action-specific assets, but it does cover some concepts you need to know. Made sure you understand these ideas:
- That the asset pipeline compiles Javascript, CSS, and other assets so that Rails servers can cache assets for better performance.
- That manifest files use commands like
require
,require_tree
, andrequire_self
to indicate which files are compiled together. - That in order for the asset pipeline to work properly in production, you need to manually run
rake assets:precompile
to produce the compiled, minified assets in thepublic
directory.
These ideas are the minimum "need-to-know" pieces of information about the asset pipeline. If you don't already understand these ideas, you don't have an "expert or enthusiast" level of knowledge about the pipeline, and unfortunately, SO isn't the right place to learn this stuff. Fortunately, the the Rails Guide to the Asset Pipeline is a short 15-minute read and can get you up to speed quickly if you need it.
Second, these are the changes you need to make in order to ensure that the asset pipeline correctly sees and handles your new print.css
file.
Follow these steps:
- Add your
print.css
file toapp/assets/css
. - You'll need to create a manifest file that will show Rails where to find
print.css
. You need to do this, even though you only have a single CSS file you're adding. This is an easy step:- Add a file called
print.js
toapp/assets/javascript
. - Add this line to
print.js
:
- Add a file called
//= require print
This will be the only line in the entire print.js
file. If I understand correctly, Rails expects manifest files to have the file extension .js
, which is why we aren't using print.css
as the manifest file.
- We now need to instruct Rails to find and use the
print.js
manifest. Add the following line in yourconfig/application.rb
file:
config.assets.precompile += %w( print.js )
- We're almost finished! However, the already-present
application.js
manifest includes the line//= require_tree .
which means that it will include yourprint.css
file. This will cause yourprint.css
styling to affect your entire site, not just the single view. There are two ways of dealing with this:- If
application.js
andprint.js
do not share any assets, you can use thestub
command in yourapplication.js
to exclude the assets used inprint.js
. What this does is instructapplication.js
to remove any of the assets thatprint.js
references from its own list of referenced files. Our modifiedapplication.js
looks like:
- If
(snip...)
require_tree .
stub print
See this answer for more information.
- If your
print.js
andapplication.js
files share some assets, you'll need to move all of the assets used byapplication.js
into subdirectories. I didn't do this myself, so I'm not the most help in this area. Look at this answer for instructions.
Now we have included print.css
in the asset pipeline. We now need to direct Rails to use print.css
in your specific view.
Let's say your action is in the reports
controller, and that the action is named print_reports
. This means we have a reports_controller.rb
file and a print_reports.html.erb
(or .haml
) file. We need to make several changes to these files.
- To start, add a new layout in
app/views/layouts
. Perhaps call itprint.html.erb
. We'll use this new layout for yourprint_reports.html.erb
file. Set it up as you desire. For a page intended to be printed, this will likely be very simple, such as
<html>
<head>
<title="Print">
</head>
<body>
<%= yield %>
</body>
</html>
Using a separate layout the disadvantage that it's difficult to keep this layout and the layout used by the rest of the application in sync, but if you are using separate CSS files for the action, it's unlikely that you want the layout to be the same anyway.
- Add a
stylesheet_link_tag
in the layout's header pointing to yourprint.css
:
<html>
<head>
<title="Print"/>
<%= stylesheet_link_tag "print" %>
</head>
<body>
<%= yield %>
</body>
</html>
- In the controller, we'll tell Rails to use our new layout for the action. Add the line
layout 'print', only: [:print_reports]
to your controller:
class reports_controller < ApplicationController
layout 'print', only: [:print_reports]
#snip
See this question for more information and a few different approaches.
At this point, when you run the app, your print_reports
action should be using print.css
correctly!
Remember to run rake assets:precompile
before deploying on the server.
Vendor CSS stylesheets in Rails 3.1 and the asset pipeline
I have exactly your configuration, it works fine. Are you sure you're requiring bootstrap in your application.css? Like:
/*
*= require bootstrap
*= require_self
*/
Related Topics
How to Change the Bootstrap 4 Navbar Button Icon Color
What Does Auto Do in Margin: 0 Auto
How to Target a :Before or :After Pseudo-Element With a Sibling Combinator
How to Set Up Fixed Width For ≪Td≫
How to Create a Curve on the Top of a Background
Css to Prevent Child Element from Inheriting Parent Styles
Disable Antialising When Scaling Images
Background Image for Select (Dropdown) Does Not Work in Chrome
CSS Div Stretch 100% Page Height
Svg in Img Element Proportions Not Respected in IE9
Difference Between :First-Child and :First-Of-Type
Select All Child Elements Recursively in Css
What Do "Flex" and "Justify-Content" Achieve That "Text-Align" Doesn'T
Using Rails 3.1 Assets Pipeline to Conditionally Use Certain Css
Meaning of Numbers in "Col-Md-4"," Col-Xs-1", "Col-Lg-2" in Bootstrap
Css to Make an Empty Cell'S Border Appear
Force Refresh of Cached CSS Data
Webkit CSS Animation Issue - Persisting the End State of the Animation