24

I have some code inside an HTML document. The code itself is not important – I've used lorem ipsum to make this clear.

<pre><code>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed sit amet diam sit amet sem accumsan faucibus ac in arcu.
Quisque varius, erat vel euismod ornare, libero orci laoreet velit, at lobortis sem nisl et eros.</code></pre>

I've applied white-space: pre-wrap to the code block to force long lines to wrap as necessary. I'd like to know whether it's possible to indent the wrapped portion of the wrapped lines, to give something like this:

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed sit amet diam sit amet sem accumsan faucibus ac in arcu.
Quisque varius, erat vel euismod ornare, libero orci laoreet velit,
        at lobortis sem nisl et eros.
davidchambers
  • 23,918
  • 16
  • 76
  • 105

6 Answers6

13

It is kind of possible... I'm not using using the <pre> and <code> tags and I'm not sure how important these tags are to you... but I've been able to get the style you're looking for and mimick the formatting as best as I could. Check it out.

http://jsfiddle.net/PVZW5/7/

CSS

div {
    margin-left:24px;
    width:400px;
}

p {
    font-family: "Courier New", Courier, monospace;
    font-weight: normal;
    font-style: normal;
    font-size: 13px;
    margin:0 28px;
    text-indent: -28px;
}

HTML

<div>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    <p>Sed sit amet diam sit amet sem accumsan faucibus ac in arcu.</p>
    <p>Quisque varius, erat vel euismod ornare, libero orci laoreet velit, at lobortis sem nisl et eros.</p>
</div>

Take a look at this SO question and some solutions that have come from it. It is relevant to your question. It might be worth your time to take a look :)

I hope this helps!

Community
  • 1
  • 1
Hristo
  • 45,559
  • 65
  • 163
  • 230
  • This doesn't respect line breaks within the code block, unfortunately. The start of _every_ line should be flush left, not just the first line within the code block. I appreciate the jsfiddle link, though. – davidchambers Aug 14 '10 at 07:43
  • 1
    @davidchambers... I didn't realize that you had new lines in your code. I'll go back and see if I can do it. – Hristo Aug 14 '10 at 12:25
  • 2
    @davidchambers... please take a look at my post. I updated the link with the new solution as well as the CSS and HTML. I hope this helps you. If this isn't what you're looking for... then I don't think you can do what you using only CSS. You might have to resort to JavaScript (I recommend jQuery). – Hristo Aug 15 '10 at 18:01
  • 1
    While I appreciate the links, defiling code snippets with paragraph tags (or tags of any nature) is not an option I'm willing to consider. Now that I'm fairly sure that I haven't overlooked an obvious solution I plan to raise this issue on the www-style mailing list. – davidchambers Aug 16 '10 at 04:53
  • @davidchambers "Defiling" code snippets? Not an option you're willing to consider? This isn't going to ruin the code somehow; people use markup in their code all the time, if they want to to group it together into logical pieces which may be styled (see, for instance, the syntax highlighting of code snippets here on StackOverflow). I don't think you're going to get much traction on www-style suggesting something that can simply be solved by marking up your paragraphs instead of relying on white-space for your paragraph boundaries. – Brian Campbell Sep 21 '10 at 00:35
  • I guess you could do this with some JavaScript (or jQuery), but as far as a PURE CSS solution, I don't think one exists as far as I know. Please let me know if the "www-style" mailing list people get back to you. – Hristo Sep 21 '10 at 02:01
  • Brian, please note that the "lorem ipsum" in this perfunctory example is representative of programming code (a Python snippet, perhaps) rather than prose. While I completely agree that marking up prose using paragraph tags and the like is the correct approach, appropriate semantics do not exist for marking up code. This is nice, in a way, since the only markup that one need apply to a code snippet is `
    ` ... `
    `. The downside, though, is a lack of styling hooks; a suitable pseudo-element would solve this problem.
    – davidchambers Sep 21 '10 at 04:17
  • Hristo: Will do! (I've been waiting to see whether someone would provide a CSS-only solution in this thread. I've now accepted that currently such a solution almost certainly does not exist, so I'll raise the issue on the mailing list and report back.) – davidchambers Sep 21 '10 at 04:21
  • @Brian... sounds good. Looking forward to hearing what the CSS people have to say – Hristo Sep 21 '10 at 04:52
  • @davidchambers Yes, I realize that it's a stand-in for code. My point was that it won't break anything to use a tag like `

    ` for formatting your code, especially for a case like this, in which you want to treat each line as a separately indented paragraph. And you will need to add more tags to your code if you want to do anything like syntax-highlighting.

    – Brian Campbell Sep 21 '10 at 05:23
  • The www-style thread is at http://old.nabble.com/%22Line%22-pseudo-element-required-to-control-indentation-of--pre-formatted-text--td29768752.html. fantasai's comments are promising, particularly that which suggests extending the `text-indent` property to allow `text-indent: 2em hanging each-line`. – davidchambers Sep 28 '10 at 01:56
12

Unfortunately after much searching I've come to believe that this is currently impossible using CSS alone. What's required is a pseudo-element for each "line" (text matching /^.*$/m), which would enable the indentation of lines beyond the first to be controlled via CSS.

I raised this issue on the www-style mailing list. fantasai's responses are promising, particularly the suggestion that the text-indent property could be extended to allow text-indent: 2em hanging each-line.

davidchambers
  • 23,918
  • 16
  • 76
  • 105
  • I believe XHTML 2.0 wanted to introduce `line` as a replacement for `
    ` but it fizzled out for want of an upgrade path.
    – ssokolow Sep 20 '10 at 10:30
  • What's really ideal is to be able to indent by a variable amount such that a wrapped line is always indented more than the initial line... but in a CSS-only solution, I'd settle for a fixed indent. – Qwertie Jul 01 '14 at 18:28
  • 1
    I'm trying to do the same thing, and after enabling the flag in Chrome, `text-indent: 2em hanging each-line` seems to only apply to `

    ` tags, and not `` elements. Maybe someday though!

    – IanVS Aug 27 '21 at 19:35
6
text-indent: -2em;
padding-left: 2em;
William Niu
  • 15,798
  • 7
  • 53
  • 93
  • 7
    This doesn't respect line breaks within the code block, unfortunately. – davidchambers Aug 14 '10 at 07:48
  • 1
    I think you meant it doesn't behave as you wanted it :-) If you want a new line "unindented", you should make it a paragraph, i.e.

    , and style it appropriately.

    – William Niu Aug 14 '10 at 11:02
0

Not currently possible just with CSS, but with the help of a scripting language ...

PHP

echo '<pre id="the_pre_id"><div>'.str_replace("\n",'</div><div>',$text).'</div>';

or JavaScript

var el = document.getElementById('the_pre_id');
el.innerHTML='<div>'+el.innerHTML.replace(/\n/g, '</div><div>')+'</div>';

Note, you only need to choose one of the above snippets. Both accomplish the same thing.

We pollute the markup (non-semantic tags), but it allows us to create per-line style rules:

CSS

pre{
    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+ */
}
pre > div {
    padding-left: 1em;
    text-indent: -1em;
}

And we have exactly the effect you're looking for ...

Result

Lorem ipsum dolor sit amet, consectetur
   adipiscing elit.
De malis autem et bonis ab iis animalibus,
   quae nondum depravata sint, ait optime
   iudicari.
Quae cum praeponunt, ut sit aliqua rerum
   selectio, naturam videntur sequi; Quasi
   ego id curem, quid ille aiat aut neget.

Stephen M. Harris
  • 7,163
  • 3
  • 38
  • 44
-1

I'm not sure if this works in <pre>, but it looks promising.

http://www.ehow.com/how_2382848_hanging-indent-css.html

DLH
  • 2,771
  • 3
  • 23
  • 30
  • This approach would work if each line of code were in its own element. Some JavaScript syntax highlighters replace code blocks with ordered lists, allowing CSS to control the indentation of wrapped lines. I'm seeking a CSS-only solution, however. – davidchambers Sep 14 '10 at 04:33
  • Link seems broken – Kryptoxx Jun 10 '20 at 14:52
-1

This article has a solution using the first-of-type pseudo selector that seems to work so far for me: http://thenewcode.com/50/Classic-Typography-Effects-in-CSS-Hanging-Indent

html{
  margin-left: 100px;
}
p {
 margin: 6em inital;
  width: 300px;
}
p:first-of-type {
 text-indent: -4em;
}
<p>Leverage agile frameworks to provide a robust synopsis for high level 
overviews. Iterative approaches to corporate strategy foster collaborative
  thinking to further the overall value proposition.</p>
<p>Bring to the table win-win survival strategies to ensure proactive domination. 
At the end of the day, going forward, a new normal that has evolved from 
generation X is on the runway heading towards a streamlined cloud solution. 
  User generated content in real-time will have multiple touchpoints for offshoring.</p>
Necromancer
  • 390
  • 5
  • 15
  • 2
    That's a useful technique but it does not answer the question. The question asks about targeting wrapped lines *within in single element*. – davidchambers May 09 '18 at 18:27