Skip to main content

The semantic, cross-browser, cross-platform method to display code segments either on a web page or into print. Optionally with added styling and striped via JavaScript.


See updated article: Displaying code in a web page

25th January 2016

Easily add example code to your web page. Beautifully handles JavaScript, CSS, HTML, and PHP. Minimum fuss—Maximum effect.

Original resource follows, kept purely for reference:

Displaying code in web pages

I started this project (25th June 2k6), to display HTML, CSS or JavaScript code blocks, with a list of requirements:

Requires rewrite to describe current usage. This article doesn't reflect actual styling.

  1. Reduce time spent creating code examples
  2. Be semantically meaningful (X)HTML
  3. A cross-browser, cross-platform solution
  4. Not break the visual layout
  5. Keep within a set width
  6. Maintain white-space for clarity
  7. Be easy to cut & paste
  8. All visual styling via CSS
  9. Optionally stripe each line of code for readability
  10. Unobtrusive JavaScript
  11. Work independently of CSS and / or JavaScript.


Here's an example from the style sheet:

/* Correctly stating the code and pre elements is the core principle.*/
/* Coded here as a single line to demonstrate long lines and how it scrolls. */
pre { font: 100% courier,monospace; border: 1px solid #ccc; overflow: auto; overflow-x: scroll; width: 90%; padding: 0 1em 1em 1em; margin: 1em auto 2em auto; background: #fff7f0; color: #000 }
code { font-size: 120% }

So what was wrong with the old methods?

I was tired of seeing web pages break from overflow incorrectly applied. (X)HTML and style sheets were being misused to make the code fit into pages. And since wrap="off" was deprecated even textarea didn't function well enough.

Most methods either break the design, don't readily cut and paste, or use quick-fix textboxes.

So what's different?

The technique demonstrated begins with a semantic cross-browser cross-platform method, then adds visual styling using CSS, and finally colouring via unobtrusive JavaScript.

As a demo, each of the code areas on this page use the method. I'll be retro fitting to the rest of the site as time becomes available (read "never").

The coding specifics


Keeping the (X)HTML semantic is the best method of ensuring cross-browser cross-platform compatibility. Don't get me wrong standards are not the "be all and end all" of web development, far from it, but they should always form the basic building block.

So the mark-up used:

A block level element which pre-formats it's contents in a fixed width font, retaining white-space and line-breaks and that's with or without CSS
W3C: Preformatted text: The pre element
An inline element which perfectly describes the intended content.
W3C: Phrase elements: The code element

<pre><code class="codelist">
//    code to display which may be wider than the width of the content area
//    Note all &, > and < characters must be replaced with &amp;, &gt; and &lt;

A similar effect could be achieved by additionally styling the code element, but then formatting is lost without CSS.

The codelist class is provided purely as a hook for the JavaScript. It is possible to achieve the result without the class but I like to allow for cases where line highlighting is not required.


Except for line colouring, all that is needed is a little style:

pre  {
    font: 100% courier,monospace;
    border: 1px solid #ccc;
    overflow: auto;
    overflow-x: scroll;
    width: 90%;
    padding: 0 1em 1em 1em;
    margin: 1em auto 2em auto;
    background: #fff7f0;
    color: #000
code { font-size: 120% }
.odd  { color: #600; background: #fff7f0 }
.even { color: #006; background: #fff7f0 }
.rem  { color: #060; background: #fff7f0 }

It is always best to assume nothing when styling. I always used to remove browser defaults when coding then rebuild. It helps ensure similar rendering across different browsing technologies. Consequently:

  1. font size and family are restated. A nice mono-spaced font, just like a real text editor bless.
  2. The border stated defines the area visually. It looks damn strange with scroll bars without one.
  3. The two overflow statements have the combined effect of only allowing horizontal scroll bars.
  4. Take care with when stating widths. Avoid 100%, IE doesn't like it especially when mixed with padding.
  5. Top padding is set to 0 to compensate for an extra line which is generated because the code starts with a new line in the (X)HTML.
  6. If you state a foreground colour it is advisable to re-state the background colour too.
  7. It may be necessary to add a font-size for code too as different browsers apply different sizing. Remember this may not be the only place it is used, for example there are code elements used throughout this content
  8. The classes; odd, even and rem; are used by the JavaScript to apply text colouring.


I recently noted that print styles were not behaving, so here's the update:

@media print{

  #content pre {
    overflow-x:visible; overflow-y:visible; overflow:visible;
    border:1px solid #ccc;
    padding:0.5em 1em;
    white-space:pre-wrap;       /* css-3 */
    white-space:-moz-pre-wrap;  /* Mozilla, since 1999 */
    white-space:-pre-wrap;      /* Opera 4-6 */
    white-space:-o-pre-wrap;    /* Opera 7 */
    word-wrap:break-word;       /* Internet Explorer 5.5+ */

  code {font:medium/150% times,serif; color:#003}
  pre code {font:small/130% courier,monospace}

The JavaScript

JavaScript is not required for the above to work. It adds text highlighting to each line.

The onload addEvent function

These days I always include an on page load handler. Which allows multiple onload routines to be run concurrently. My function of choice is Simon Willisons' excellent add load event.

function addEvent(func){
if (!document.getElementById | !document.getElementsByTagName) return
var oldonload=window.onload
if (typeof window.onload != 'function') {window.onload=func}
else {window.onload=function() {oldonload(); func()}}


Upon page load the functions stripeCode() and selectCode() are called.

The stripeCode function

The function stripeCode() does the text highlighting. "So what" I hear you say, "there's a lot of stripe functions available" (an excellent one may be found at Splintered ). Unlike lists and tables code elements do not have child elements to attach colour to. Consequently the usual stripe methods do not work.

There are no elements inside the code element to hook onto to create different coloured lines. Consequently I decided to create a new code structure from the existing content.

This requires:

  1. find and effect each occurrence of codelist
  2. create a new code element and initialise variables
  3. find the end of line marker
  4. check each content character stopping at an end of line marker. Not so easy given different browsers use different variations.
  5. create a new span element add a line of content and apply a colour class
  6. add to the new code element and reset variables
  7. finally replace the old code element with the new one.

Firstly a standard technique for working through the DOM to access the relevant content.

Test for an end of line marker. Because of the (X)HTML layout the first character(s) are markers. I reverted to old school JavaScript as I couldn't get modern methods to work in a consistent manner. There must be a simpler and quicker method, any ideas?

Remember this is a rendered document; IE uses a carriage return (#13), Firefox uses a linefeed (#10) and Opera (most correctly) used both (#13,#10).

function stripeCode(){

// Locate and isolate pre followed by code with a class of codelist
var pres=document.getElementById('content').getElementsByTagName("pre")

for (var g=0;g<pres.length;g++){
var cn=pres[g].firstChild.className;
if (cn=="codelist"||cn=="css"||cn=="html"||cn=="javascript"||cn=="php"){

  // create a new code element
  var newCode=document.createElement('code');

  // reset variables;

  // even: for odd or even line
  var even=false;

  // line content container
  var spanContent="";

  // codeContent= all the code elements content
  var codeContent=pres[g].firstChild.firstChild.nodeValue;

  // first character(s) should be the carriage return and or a line feed
  var crLF=codeContent.charAt(0);
  if (codeContent.charCodeAt(1)==10) crLF+=codeContent.charAt(1);

If a line contains "//" then the whole line is coded as a comment. Note multi-line comments are not catered for.

  // now work through the content character at a time
  for (var f=0;f<codeContent.length;f++){

    // test for an "end of line"
    if (codeContent.substr(f,crLF.length)==crLF){

      // check for CR and LF step if required
      if (codeContent.charAt(f+1)==crLF[1]) f++;

      // create a new span as the lines container
      var newSpan=document.createElement('span');

      // apply a class

      // check to see if its a comment
      if (spanContent.match("//")){
        even= !even;

      // if no content add a space
      if (spanContent==""){
        spanContent=" ";
        even= !even;

Please remember that only about 18 lines of code can be seen at screen resolutions of 800x600px. Splitting the code into smaller segments is advisable.

      //add line content

      // add new line to the new code element

      // add CR or LF if required
      if (crLF.length==1) newCode.appendChild(document.createTextNode(crLF));

      // flip odd / even boolean
      even= !even;

      // reset line container

    // otherwise add character to line container
    else spanContent+=codeContent.charAt(f);

  // finally replace old code element with the freshly created one

A commented file of the JavaScript is available: stripe.code.js.

Update: Displaying code in a web page