14

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 http://tardate.com/syntaxhighlighter/line-continuation-example.jpg

lauhub
  • 894
  • 1
  • 15
  • 27
tardate
  • 16,424
  • 15
  • 50
  • 50
  • You should consolidate the solution into an answer. – NGittlen Dec 07 '08 at 04:22
  • 4
    I've done that in the question itself "The Solution so far..". I can't edit the best answer I received, and I don't want to take away the rep by creating my own answer (the answers I get deserve the credit!). Trying to work within the parameters of SO.. – tardate Dec 07 '08 at 06:00

4 Answers4

4

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*/
}
Jack Ryan
  • 8,396
  • 4
  • 37
  • 76
  • that's great! Although you got the horizontal and vertical positioning back to front. This works for me in IE/FF: background: transparent url(wrap-cont.png) no-repeat 0 12px; – tardate Dec 01 '08 at 11:31
  • Excellent! I'm glad to hear it! I like the ol for line numbers suggestion by Ant P. Its probably better semantically too. – Jack Ryan Dec 01 '08 at 12:07
  • Note that I've collated and summarised the best solution in the question itself – tardate Dec 07 '08 at 06:02
2

I've found a solution very similar to Jack Ryan's, but with the 'continuation' character at the end of the line. It also indents the continued lines.

The CSS:


p {
  font-family: Arial, Sans-Serif;
  font-size: 13px;
  line-height: 16px;
  margin: 0 0 16px 0;
}

.wrap-cont {
  font-family: Courier New, Monospace;
  margin-bottom: 16px;
  width: 400px;
}

.wrap-cont p {
  background: url(wrap-cont.gif) no-repeat bottom right;
  text-indent: -32px;
  margin: 0 0 0 32px;
  padding-right: 16px;
}

The HTML:


<p>For example, you may have a really long command line to display, like this:</p>
<div class="wrap-cont">
  <p>c:\Program Files\My Application\Module\bin\..&gt; 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"</p>
  <p>c:\Program Files\My Application\Module\bin\..&gt; 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"</p>
</div>
<p>Stackoverflow forces a line like this not to wrap.</p>
  • Thanks Maarten. But positioning "bottom right" means you get the continuation glyph on _every_ line (even non-wrapped) since it is not using Jack's trick of rendering below the visible box. Come close with: background: url(wrap-cont.png) no-repeat right 16px; – tardate Dec 01 '08 at 11:34
1

This cannot be done with CSS. Sorry. :(

eyelidlessness
  • 62,413
  • 11
  • 90
  • 94
1

If you want it to be unambiguous, you'll have to add markup. I'd suggest using an <ol> with one list item per line of code, because that way you get line numbering for free. If this is too much work to do across the site, you could always add it using Javascript.