Cleanest way to give the body tag an id?

I'm implementing a design where on every page the body has a different id, which sets some of the styling rules. There's only a couple of distinct layouts which get re-used on every page. I can think of a few different ways to set the body id but i'm not super-happy about any of them and thought i'd see what you guys think.

approach 1) use an instance var from the controller

#controller - in each action @body_id = "createQuiz"

#layout <body id="<%= @body_id %>">

I'm not keen on this as it seems like bad seperation of concerns - to have something that purely relates to styling defined in the controller. Also, it pollutes my controller actions - i use the resource_this plugin which dynamically generates the standard restful controller actions which i tend to try to stick as closely to as possible. With resource_this you don't even define the action unless you want it to deviate from the norm. So, i'd need to start defining all my actions just so i could stick this @body_id definition in there. urggh.

approach 2) set in the controller in a before_filter

#controller class before_filter :set_body_id

protected def set_body_id   ids = {"edit" => "createQuiz",          "show" => "viewQuiz",           etc}   @body_id = ids[action_name] end

approach 3) yield in the layout

#layout <body id="<%= yield :body_id %>">

#view <% content_for :body_id do %> createQuiz <% end %>

or something similar. This is good as everything's now on the actual view page in question but it seems like an ugly, hacky and error prone solution.

Any thoughts?

Max Williams wrote:

I'm implementing a design where on every page the body has a different id, which sets some of the styling rules.

Don't ever do that. If you need a special stylesheet for a particular page, then include a special stylesheet

. There's only a couple of distinct layouts which get re-used on every page.

Then use an application-wide CSS file and a page-specific one. The body tag shouldn't have an ID attribute.

Best,

While I completely agree with Marnen, I feel that still leaves you with almost the same issue, when and how to call in the needed stylesheet. Here is my input:

Define a function that will determine which file to include in the helper file for the class in question (app/helpers/xxx_helper.rb). It would look something like this:

  def custom_css_include     css_file = case controller.action_name       when 'edit': 'createQuiz.css'       when 'show': 'viewQuiz.css'     end     "#{story_type}"   end

and then in your view (in the <head>):

  <link rel="stylesheet" type="text/css" src="file/path/<%= custom_css_include %>" />

you may even be able to shorten that by still being able to use the rails stylesheet_link_tag. Not sure, I haven't tested it.

oops, that story_type there should be css_file. I copied it out of one of my projects.

Thanks guys.

I agree - i don't like having an id on the body tag - but for the sake of argument let's say that i'm unable to do anything about this and have to work with the styling rules i've been given (which are all in a single stylesheet btw). This isn't necessarily true but i don't want to make an issue out of it right now.

As i said i have a single stylesheet, so deciding which stylesheet to include isn't the issue. If you were forced to set the id of the body (for the sake of argument), how would you do it?

thanks a lot, max

Max Williams wrote:

Thanks guys.

I agree - i don't like having an id on the body tag - but for the sake of argument let's say that i'm unable to do anything about this and have to work with the styling rules i've been given (which are all in a single stylesheet btw). This isn't necessarily true but i don't want to make an issue out of it right now.

If it isn't necessarily true, then I'm not going to act as if it is.

As i said i have a single stylesheet, so deciding which stylesheet to include isn't the issue. If you were forced to set the id of the body (for the sake of argument), how would you do it?

I wouldn't. I'd take the stylesheet I was given and split it into several stylesheets.

thanks a lot, max

Best,

Is there are reason why the part you want to manipulate can’t be in a div of it’s own and that have an id?

Peter Hickman wrote:

Is there are reason why the part you want to manipulate can't be in a div of it's own and that have an id?

Hi Peter

I'm not sure what you mean, sorry. Can you give an example that relates to my earlier examples?

thanks, max

Peter Hickman wrote:

Is there are reason why the part you want to manipulate can't be in a div of it's own and that have an id?

That would work, but in this case it's really no better. The body-with-id pattern is an all-too-commonly seen kludge that results from not understanding how to organize CSS properly. The solution is to organize the CSS properly!

Best,

I've already completed a themes / layout based system and it works very well.

You should divide the stylesheets up and handle the different pages with page-specific layouts which include the specific stylesheet for that page.

Then you just render the layout in your controller for that page.

respond_to do |format|   format.html { render :layout => @layout_name } end

Marnen - i totally get your point, i should stick my feet in the mud and refuse to go along with this crazy scheme.

However, let's exercise our fantasy muscles and stick with the science-fiction scenario where i have to implement the design i've been given, as is. :slight_smile:

Max Williams wrote:

Marnen - i totally get your point, i should stick my feet in the mud and refuse to go along with this crazy scheme.

Good. Then stop trying to do otherwise.

However, let's exercise our fantasy muscles and stick with the science-fiction scenario where i have to implement the design i've been given, as is. :slight_smile:

No. It's a bad idea, and you don't have an actual use case for it. There is no reason for either of us to spend any more effort on it -- particularly since you already have several answers hidden in this thread (not all of them by me).

Best,