Why does HTML5 recommend putting the code element inside pre?
Asked Answered
I

5

71

The HTML5 documentation recommends putting the code element inside the pre element, but I don't understand how this is better or more semantic than just using the code element and CSS. In their own example:

<pre><code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code></pre>

Could also be written (Making some assumptions about the browser's defaults for pre):

<style>
code {
    display: block;
    white-space: pre;
}
</style>
…
<code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code>

Even if the pre is there to distinguish a code block from an inline string of code, I don't see it being a more semantic choice than specifying the block-ness of the code in a class.

Is there a specific reason the pre is recommended over a CSS solution?

Intercostal answered 31/7, 2012 at 14:53 Comment(7)
because <code> while does apply a fixed-width font, it does not apply any line-break honoring as <pre> will. e.g. applying <code> to formatted code will break the formatting. This is somewhat of an oversight in the original definition of <code>, and now we're stuck with it for backwards compatibility.Isolda
The documentation don't "recommend" it, it just shows it as an example. "[the example] shows how a block of code could be marked up using the pre and code elements."Ragg
@MarcB I don't think it's an oversight. As I said in my question, code is also useful for inline code strings. But that doesn't make pre a better solution than CSS for block formatting.Intercostal
@Rocket that's a good point, but I'm not the only person to take that example as a recommendation. PrismJS does the same thingIntercostal
Don't you mean white-space: pre; in the css snippet?Jaramillo
@Xec yes, I do! I must stop doing three things at once. :(Intercostal
@Intercostal deep breaths, think of a calm blue ocean. also, add a dash to white-space? :)Jaramillo
B
78

<code> represents only a "fragment of computer code". It was originally thought for simple code snippets like i++ or <code>.

<pre> "represents a block of preformatted text, in which structure is represented by typographic conventions rather than by elements". It's original purpose was nothing more than exactly this: provide a text in the same way it was given by the author, e.g.

+----------------------------------+
|                                  |
| WARNING! PREFORMATED TEXT AHEAD! |                      =o=
|                               __;                                  ~^
+----------------TT------------°
                 ||    _____________    _____________________
                 ||    | TO GRANDMA  >  | TOTALLY NOT A TRAP  > 
  oÖo            ||    |°°°°°°°°°°°°    °°°°°°°°°°°°°°°°°°°°°          
   |  ö          ||    |                |      .mm,                    
~"""~"""~"""~"""~"""~"""~~"""~"""~"""~"""~"""~"""~"""~"""~"""~""..MWMWc...~"""~""

You don't need to use each with each other. <pre> has its own roles, like <code> has its own. However, <pre> is a way to signalize that the white-space in the given fragment is important, a role that <code> is missing.

However, back to your question: note the exact wording:

The following example shows how a block of code could be marked up using the pre and code elements.

<pre><code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code></pre>

A class is used in that example to indicate the language used.

It says could, not should. You're free to do this how you want. It's not recommended by the W3C in any way, however, I personally recommend you to use <pre><code>....

Further explanation

Whenever white-space is part of your code and the structure of your code, you should state that this structure should be kept. As the structure in code is given by typographic conventions (tabs, linefeeds, spaces) I personally recommend you to use <pre><code>, even if it's arguably more code and another node in the DOM. But whenever missing white-space will render your code imperfect it's necessary.

Apart from that you can easily differ between inline code and code-blocks without checking element.className, and some JS syntax highlighter work pretty well with <pre><code>... and strip the <code> automatically.

Also, if you use a general rule for <code> with white-space:pre;, you cannot use it for inline snippets without additional classes. If you were to create a class instead, you've won nothing compared to <pre><code>.

References

  • W3C: HTML5: 4.5.12 The code element (W3C Recommendation 28 October 2014)

    The code element represents a fragment of computer code. This could be an XML element name, a file name, a computer program, or any other string that a computer would recognize.

  • W3C: HTML5: 4.4.3 The pre element (W3C Recommendation 28 October 2014)

    The pre element represents a block of preformatted text, in which structure is represented by typographic conventions rather than by elements.

Bowl answered 31/7, 2012 at 15:8 Comment(8)
This is a well-thought-out answer, but I'll pose the same followup I posed for Quentin: So then I should use pre for code with significant whitespace, and CSS for code where the whitespace is presentational?Intercostal
Whenever white-space is part of your code and the structure of your code, you should state that this structure should be kept. As the structure in code is given by typographic conventions (tabs, linefeeds, spaces) I personally recommend you to use <pre><code>, even if it's arguably more code and another node in the DOM. (Apart from that you can easily differ between inline code and blocks, and some JS syntax highlighter work only on <pre><code>... and strip the <code> automatically).Bowl
+1 If your goal is semantic markup, i agree with Zeta's recommendation, seeing as <pre> means preformatted and <code> means code fragment, when what you are marking up is preformatted code, using <pre><code> makes sense. If your goal is clean markup, I would go with the css white-space: pre; solution.Jaramillo
I write my programs with high degree of formatting. So writing <pre><code> kicks in my OCD. If I write the <code> in the next line, it will cause additional newline and spaces in the output. Couldn't I just write <pre> inside <code>? Doesn't that make more sense, since its the actual computer-code that is pre-formatted? I can't see anyone recommending this...Selig
@BlackPanther: code expects phrasing content, but pre isn't phrasing content. So from a standard point of view, it's not valid (in HTML4 terms: you cannot put a block element in an inline element). Also, while HTML5 seems to ignore whitespace at many points, it often doesn't. Space between elements leads to additional nodes in the DOM (at least in Gecko).Bowl
Thanks, that makes sense. I knew what was causing the additional whites-paces, but I did not want them to be there. They were caused by me writing the code in multiple lines (unfortunately not formatted in the comments): ` <pre> <code> <!-- Contents --> </code> </pre>` The tabs and newline created the whites-paces. But writing `<pre><code>' felt ugly. Looks like I will have to get used to it.Selig
@BlackPanther: If you use some kind of HTML preprocessor, you can define your own tag <codeblock>...</codeblock>. By the way, make sure to ask additional questions in independent posts. That way, you can reach a wider audience, which is helpful if the original author of the answer isn't active on StackOverflow anymore.Bowl
"Also, if you use a general rule for <code> with white-space:pre;, you cannot use it for inline snippets without additional classes."* No, that's not true, you absolutely can do that. What you cannot do with that, is including a multi-line code snippet inline. Which, frankly, makes no sense anyway, in like 99.99% of the cases.Educt
C
11

CSS is for presentation.

White space is significant (not presentational) in many programming languages.

Cockspur answered 31/7, 2012 at 14:58 Comment(3)
It should also be noted that even in programming languages that white space isn't required for (technically speaking), it is necessary in order for humans to read it easily.Finke
So then I should use pre tags for code with significant whitespace, and CSS for code where the whitespace is presentational?Intercostal
This answer makes me wonder whether <pre> is semantic markup at all, or rather like <b>, <i> (i.e., a purely representational left-over of early HTML versions).Subjunction
G
4

To represent a block of computer code, the pre element can be used with a code element;

To represent a block of computer output the pre element can be used with a samp element.

<pre><code> for block code that must not wrap. Use <code> for inline code that can wrap.

Line breaks and white spaces in the text enclosed within the <pre> tags is maintained as it is in the html document when displays on the browser.Browsers normally render <pre> text in a fixed-pitched font, with whitespace.

Gnaw answered 31/7, 2012 at 15:3 Comment(2)
This doesn't really answer the OPs question, which was "why the <pre> in the html5 example?"Jaramillo
he asked "Is there a specific reason the pre is recommended over a CSS solution?" In my knowledge i answered.Gnaw
H
-1

<pre> shows line breaks!

This prevent you using php function such as nl2br() or adding manually <br /> at every line end.

Regards, Ghost

Hydrotherapy answered 31/7, 2012 at 15:6 Comment(0)
N
-1

What makes <pre> the semantic element to display preformatted text is its default white-space property value:

white-space: pre;

If for some reason you need to override it, then using <pre> doesn't make sense any more and having an extra element in your markup is a bad practice. For example, if you prefer to wrap long strings of code, you need white-space: pre-wrap instead. In that case, here's how you can deal with inline and block codes:

code.block {
  display: block;
  white-space: pre-wrap;
  background: tan;
}

code:not(.block) {
  background: plum;
}
<code class="block">var i: Integer;
begin
   i := 1;
end.</code>

<p>The <code>code</code> element is enough.</p>

For even cleaner markup, give the class to the less common use case in your site: either class="inline" or class="block".

Northwestwards answered 22/6, 2023 at 10:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.