How to apply a line wrap/continuation style and code formatting with css


Tags: html,css

Problem :

When presenting preformatted text on the web (e.g. code samples), line wrapping can be a problem. You want to wrap for readability without scrolling, but also need it to be unambiguous to the user that it is all one line with no line break.

For example, you may have a really long command line to display, like this:

c:\Program Files\My Application\Module\bin\..> Some_really_long_command line "with parameters" "that just go on and on" " that should all be typed on one line" "but need to be wrapped for display and I'd like the text style to indicate that it has wrapped"

(Stackoverflow forces a line like this not to wrap.)

Is there a way of styling with CSS to give the same treatment as you see in books? i.e. to wrap the line, but include an image or glyph that indicates a line continuation.

Obviously I am looking for a style that can be applied to all text, and let the browser's XHTML/CSS rendering engine figure out which lines have wrapped and therefore need the special treatment.

The Solution so far..

Adding line continuation glyphs

Thanks to Jack Ryan and Maarten Sander, have a reasonably workable solution to add continuation glyphs to either the left or right of wrapped lines. It requires an image with repeating glyphs in the vertical, which is offset so that it is invisible if only one unwrapped line. The main requirement of this technique is that every line needs to be within a block (e.g. p, span or div). This means it cannot easily be used manually with existing text that is just sitting in a pre block.

The fragment below summarises the essential technique. I posted a live example here.

.wrap-cont-l {
  margin-left: 24px;
  margin-bottom: 14px;
  width: 400px;
}

.wrap-cont-l p {
  font-family: Courier New, Monospace;
  font-size: 12px;
  line-height: 14px;
  background: url(wrap-cont-l.png) no-repeat 0 14px; /* move the background down so it starts on line 2 */
  text-indent: -21px;
  padding-left: 14px;
  margin: 0 0 2px 7px;
}

.wrap-cont-r {
  margin-left: 24px;
  margin-bottom: 14px;
  width: 400px;
}

.wrap-cont-r p {
  font-family: Courier New, Monospace;
  font-size: 12px;
  line-height: 14px;
  background: url(wrap-cont-r.png) no-repeat right 14px; /* move the background down so it starts on line 2 */
  text-indent: -28px;
  margin: 0 0 2px 28px;
  padding-right: 14px;
}

To be used like this:

<div class="wrap-cont-l">
  <p>take a long line</p>
  <p>take a long line</p>
</div>
<div class="wrap-cont-r">
  <p>take a long line</p>
  <p>reel him in</p>
</div>

But wait, there's more!

I recently discovered syntaxhighlighter by Alex Gorbatchev. It is a fantastic tool for dynamically and automatically formatting text blocks. It is principally intended for syntax highlighting code, but could be used for any text. In v1.5.1 however, it does not wrap lines (in fact it forces them not to wrap).

I did a little hacking around though, and was able to add a simple line wrap option syntaxhighlighter and also incorporate the continuation glyph idea.

I've added this to the live examples and included a few notes on the hacks required (they are trivial). So with this as the text in the page:

<textarea name="code" class="java:wraplines" cols="60" rows="10">
public class HelloWorld {

  public static void main (String[] args)

  {

    System.out.println("Hello World! But that's not all I have to say. This line is going to go on for a very long time and I'd like to see it wrapped in the display. Note that the line styling clearly indicates a continuation.");

  }

}
</textarea>

This is a snapshot of the formatted result:

screenshot



Solution :

Here is one (unpleasant) way of doing this. It requires a number of bad practices. But SO is about solutions to real problems so here we go...

First each line needs to be wrapped in some sort of containing block. Span or p are probably the most appropriate.

Then the style of the containing block needs to have line height set. and a background image that contains a number of newLine glyphs at the start of every line except the first one. As this is code it would be resonable to expect it to not wrap more than 5 times. So repeating 5 times is probably enoygh.

This can then be set as the background image, and should display at the beginning of every line except the first one. I guess the resulting CSS might look like this:

p.codeLine
{
    font-size: 12px;
    line-height: 12px;
    font-family: Monospace;
    background: transparent url(lineGlyph) no-repeat 0 12px; /* move the background down so it starts on line 2 */
    padding-left: 6px; /* move the text over so we can see the newline glyph*/
}

    CSS Howto..

    How to make text wrap nicely below start of first line

    How to set variables in LESS from a dynamic website?

    How can I make my an image?

    How to conditionally add css class in view in web2py?

    How to css this little button next to