The correct way to handle pre tag

There are two things that we have to remember when we want embed some code on our website: it should be highlighted and easy to copy.

Adding code

To add code, we’ll use this structure:

1
<pre class="prettyprint"><code>...</code></pre>

Code highlighting

This is easy, we can use Google Code Prettify, it’s easy to setup and quite universal. We just have to add some CSS and JavaScript, it’s all well described here.

Adding “copy” functionality

The idea is simple:

When user clicks on code then it is replaced with textarea where the code itself is added and selected. When the textarea loses focus, it is reverted to original state.

To accomplish this, we’ll use jQuery. Okey, now let’s write some JavaScript.

1
2
3
$("pre").delegate("code", "click", function() {
// Code
});

Each time we click on code tag that is in pre tag, the function is called

1
2
3
4
5
var $code = $(this),
$pre = $(this).parent(),
$clone= $code.clone(),
text = $code.text(),
height= $code.outerHeight();

Now we’re just setting some variables

1
2
3
$code.replaceWith($('<textarea/>'));

var $textarea = $pre.children('textarea');

We’re replacing code tag with textarea and add it to variable

1
$textarea.height(height).val(text).select();

We’re setting height for textarea as it was for code tag, add text and select it.

1
2
3
$textarea.one('blur', function() {
$textarea.replaceWith($clone);
});

When textarea loses it focus, everything is reverted back

At the end, code will look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$("pre").delegate("code", "click", function() {
var $code = $(this),
$pre = $(this).parent(),
$clone= $code.clone(),
text = $code.text(),
height= $code.outerHeight();

$code.replaceWith($('<textarea/>'));

var $textarea = $pre.children('textarea');

$textarea.height(height).val(text).select();
$textarea.one('blur', function() {
$textarea.replaceWith($clone);
});
});

And that’s all, with this code you can add really great user experience. I’ve used this technique on this blog so you can test it as you read this post.