Making an Expanding Code Box

Posted on: July 9, 2009 by Chris Coyier

On blogs that like to share snippets of code like this one, it is common to use the <pre> tag to wrap the code so that the spacing/indenting is maintained and long lines do not wrap. While this is desirable behavior, it can be undesirable to have those un-wrapped lines break out of their containers awkwardly and overlap other content.

On Digging Into WordPress, we use JavaScript (jQuery) to solve this problem. One solution could potentially be to use only CSS and expand the width with something like pre:hover, but JavaScript is more elegant:

  • Expands only when needed
  • Expands only to as wide as needed
  • Expands with animation

The CSS

The <pre> tag is naturally block-level, so this is what we’ll use to style our code blocks and hide the overflow.

pre { 
  background: #eee; 
  padding: 10px; 
  border: 2px solid #c94a29; 
  overflow: hidden;
  margin: 0 0 15px 0; 
  width: 563px; 
  font-family: Courier, Monospace;
}

The jQuery

The real trick here is that the code blocks are wrapped not only in <pre> tags but also in <code> tags. The code may ultimately get cut off by the pre block, but that inner code tag still has a natural width that can be measured by JavaScript. Here is the logic:

  1. When a pre block is hovered…
  2. Measure the internal code blocks width
  3. If that width is wider than the pre block…
  4. Expand the pre block to be wide enough to accommodate
  5. On mouseOut, return the pre block to its original size
$j("pre").hover(function() {
	var codeInnerWidth = $j("code", this).width() + 10;
    if (codeInnerWidth > 563) {
		$j(this)
			.stop(true, false)
			.css({
				zIndex: "100",
				position: "relative"
			})
			.animate({
				width: codeInnerWidth + "px"
			});
		}
	}, function() {
			$j(this).stop(true, false).animate({
				width: 563
		});
	});

Couple of things of note here. The “codeInnerWidth” is calculated on every hover, because different blocks will have different inner widths. The width of the pre blocks are hard-coded though. Calculating that on every hover leads to problems like fast mouse-in-mouse-outs expanding the box and re-calculating it’s size to be larger than it was originally. The stop function prevents queuing up of animations. Also note the $j being used is just because we are using jQuery in noConflict mode:

var $j = jQuery.noConflict(); 

Demo

None of the code blocks so far have been long enough for you to see it in action, so here is a demo block (RSS readers, obviously you need to see this on our site to see it work).

This is a really long line of code that is even longer than the world super-cala-frag-alistic-espee-ala-dosis
Thumb for Making an Expanding Code Box

Let's talk it out, folks.

  1. Benjie said on July 9, 2009:

    Actually this is a nice trick you have here on DiW… I also like the sidebar which slides to the right when you hover on it. It’s also jQuery right?

    #1
    • I don’t know about this site specifically (didn’t look at the source) but it can be done using jQuery’s .animate pretty simply.

      #1.1
  2. Benjie said on July 9, 2009:

    I check your CSS tricks site Chris…It’s pagerank is still 6

    #2
  3. This is awesome — I am thinking about using it at Perishable Press. Thanks for posting in tutorial format.

    #3
  4. Dave Blencowe said on July 9, 2009:

    I have recently been playing with jQuery and have considered using it for the pre/code tags on my site. I like the idea you have implemented here and might use something similar for my site, although I would prefer to use an expand button I think.

    #4
  5. Frank said on July 9, 2009:

    Hmm, I prefer the scrollbar. This’ll be annoying if you got a lot of code on one line, you’ll have to scroll to the right and keep your mouse on the code, but I guess it works good with a little bit of code.

    #5
  6. Chris Reynolds said on July 9, 2009:

    Very nice little effect!

    #6
  7. Awesome! Thanks for the explanation. Again, nicely done!

    #7
  8. Ida said on July 10, 2009:

    It’s nice. But I just want to point out a problem(?). I visited this site with a pretty small screen and when the code expanded a horizontal scroll was needed. That’s fine. But it gets a bit tricky when one tries to copy the code inside the block.
    I guess this could be solved by having a neat little “copy-this-code”-button though.
    Well anyway thanks for sharing!

    #8
  9. Sorry, I know it’s not really adding to the conversation, but this is really cool. Thanks for sharing.

    #9
  10. Personally, I like using the built-in WordPress shortcode [sourcecode language='whatever']. You get a scroll bar and code highlighting.

    #10
    • I thought that was only for WordPress.com accounts.. is that functionality also built into self-hosted installations?

      #10.1
      • Jeff, you’re right. I guess it would help to compare my self-install to the WordPress.com blog before hitting submit.

        WordPress.com just uses the SyntaxHighlighter plug-in globally (or at least, it’s based off this code).

        #10.1.1
  11. fx said on July 16, 2009:

    In your demo, s/world/word/ig.

    #11
  12. The copy problem is realy not a problem and is easilly solved. Include an extra empty line infront of the code and after the code. This way you place the mouse pointer above the line you need, keep the left mouse pressed and drag down passed the line you need included in the copy. Pretty basic copy behaviour, however you need the extra lines unless you drag outside the box to get the same effect.

    vertical scrollbar is never nice, however wordwrap with code is worse! Nice function, will definately include this behaviour on my own blog when I get the time.

    #12
  13. Dan said on July 25, 2009:

    Really interesting pieces of code. Thanks !

    #13
  14. Vincent said on September 28, 2009:

    I think it’s better to set the overflow via jQuery, so without JavaScript you can also read the Code.

    #14

Comments are closed. If you have something really important to add, contact us. Thank you!