Showing and hiding elements with CSS and JavaScript

* 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');
	});
Post a Comment or Leave a Trackback

4 Comments

  1. March 11, 2008 at 8:52 am | Permalink

    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…)?

  2. March 11, 2008 at 12:27 pm | Permalink

    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

  3. April 19, 2008 at 11:10 pm | Permalink

    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();

  4. April 19, 2008 at 11:49 pm | Permalink

    @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.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*