* Note: These examples reference the Prototype JavaScript framework.
Often I find that I want to load content onto a page but have its default view state as hidden until a user defined event makes it appear.
The problem is if I hide an element using a linked CSS file (with a class or Id style of {display:none;}) it seems I cannot show that element using either of the following JavaScript options:
//uses Prototype to display:block a previously hidden element
$('myEl').show();
//adds a CSS classname to the element
$('myEl').addClassName('showElement');
Where the CSS class ’showElement’ above is basically {display:block;}
Now if I add the CSS to hide the element inline like so:
<div id="myEl" style="display:none;">
Then everything works great, except now I have CSS embedded in my markup which I really don’t want there.
The Prototype API for Element.show() suggests that:
Element.show cannot display elements hidden via CSS stylesheets. Note that this is not a Prototype limitation but a consequence of how the CSS display property works.
A user on the Prototype google group sent me this link as an explanation. A quote from that page:
The problem actually only arises when you want some elements to be hidden when the page loads: there is no possible way to find out what there display should be when you show them.
The solution I used? Well something that I’ve been doing with Prototype and jQuery for a while (it’s just that I wanted to know if there was a cleaner solution in this case) is the dom:loaded observer function which will run as soon as the Dom is loaded (and before all ‘assets’ are loaded so it’s super quick).
Basically I use JavaScript to hide the element(s) I want hidden instead of CSS. This has the following benefits:
- Clean markup (no inline CSS)
- Being able to modify the ‘display’ state from a user event
- Works if the user has no JavaScript enabled (the elements will simply always be there which is better than them not!)
Example of the dom:loaded function:
Event.observe(document, 'dom:loaded', function() {
//uses Prototype to hide the element
$('myEl').hide();
//Alternative to the above example - attach a CSS class called 'hide' (with has {display:none;}) to the element
$('myEl').addClassName('hide');
});

4 Comments
As far as I can see, this seems to be a problem with Prototype, rather than JS/CSS as a whole.
I have done exactly what you describe using jQuery, and it works perfectly, and as expected.
You mention having to use your workaround in jQuery too – have you actually tried it in jQuery, or did you assume it would behave the same way as Prototype (of which, for the record, I have no working experience…)?
I must admit this particular scenario I’ve only had to do when using Prototype.
I have of course manipulated stylesheets with jQuery, just not with hiding/showing elements.
That is great news that it is possible with jQuery.
I’ll have to give it a go when I get a chance.
Thanks
The way I’ve been handling this case is similarly using the onload property of the DOM window object. I’m curious whether it’s functionally exactly the same as your solution — if so, this code is slightly shorter:
window.onload = init;
function init() {
$('myEl').hide();
}
Also, for the record, this will work with jQuery with one tiny modification. Add the pound sign for selecting an ID:
$('#myEl').hide();@Zac – Yep, jQuery will show an element which has been hidden using a style in an external .css file (display:none;).
Not really sure why Prototype has problems with this, hence the workaround.
I assume you’re not using “window.onload” if you have a JS framework in place? That would be much slower than using the “DOM ready” approach that either Prototype or jQuery provide.