0

This may seem an odd request, but I need to set the width of individual characters and have them act like normal text in a flowing paragraph. Here's an example:

http://jsfiddle.net/TGZ3K/8/

Ugliness aside, this is fine except for the fact that the words are being split in half when wrapping. Any ideas on how to work around this?

If you change display to "inline", the wrapping works but the inline elements can't be given a width.

Using letter-spacing instead of width might suffice, but I'd need to calculate something like:

width = letter-spacing - (actual character width as rendered)

But again, getting the real width of an inline element seems tricky.

The html/text side of things can't be easily modified (e.g. a solution such as adding manual line breaks and setting css nowrap), it's being sent by a separate service, so any processing of it needs to be automated.

Note: The font must be Arial, so not a fixed-width font and I need to support IE8+

Edit: Sorry, it needs to support inner formatting tags, like strong or em (example updated). This isn't normally supported in letteringjs, so i'm using this fork to prevent these tags from being stripped:

https://github.com/maranomynet/Lettering.js/blob/master/jquery.lettering.js

aaronjbaptiste
  • 554
  • 4
  • 14
  • Why don't you use the `word` option to split it in words instead of in characters? – Alvaro Sep 24 '13 at 15:36
  • @Alvaro Ah, that would have worked. However I am actually using maranoynet's fork of letteringjs which preserves tags such as and from being removed (letteringjs doens't support this, it strips them out when splitting). Splitting on "word" in both letteringjs and the fork removes these tags also. – aaronjbaptiste Sep 24 '13 at 15:43

1 Answers1

1

If you wrap each word in a <span /> element, you can set white-space:nowrap on those spans and the text inside the spans won't wrap in the middle of a word, the whole word will wrap.

Here's an example: http://jsfiddle.net/TGZ3K/4/

Note I added some JS to add the SPAN elements I'm referring to, then used the .lettering() method on those spans. I had to update the CSS for this to work properly.

Updated JS

$('p').html('<span>' + $("p").text().replace(/\s/g, '</span> <span>') + '</span>').children().lettering();

Updated CSS

p span {
    white-space:nowrap;
}

p span span {
    display: inline-block;
    width: 10px;
}

UPDATE

To support nested tags like <b /> or <em /> you can do something like this:

$('p').html('<span>' + $("p").html().replace(/\s/gi, '</span> <span>').replace(/(<b>|<em>)/gi, '</span>$1<span>').replace(/(<\\b>|<\\em>)/gi, '</span>$1<span>') + '</span>').find("span").lettering();

Where opening and closing HTML tags get wrapped in opposing <span /> tags. E.g.

some text

Turns into:

</span><b><span>some text</span></b><span>

And then the old regexp does the same with spaces which turns the HTML into:

</span><b><span>some</span> <span>text</span></b><span>

And then we start our HTML string with an opening and end the HTML string with a closing <span /> tag:

<span></span><b><span>some</span> <span>text</span></b><span></span>

There will be extra <span />s that get created but they shouldn't mess with the flow of the HTML.

Jasper
  • 75,717
  • 14
  • 151
  • 146
  • Yea, that works, but you obviously need to change the jQuery, as you did in your example. I didn't think that was an option. – Josh Crozier Sep 24 '13 at 17:35
  • @JoshC Yes, that's necessary... no way to not wrap the words in some type of element, since there is no real connection between the letters that links them together as words, so we need to make that connection somehow. – Jasper Sep 24 '13 at 17:37
  • When I made that original comments stating it didn't work - it didn't work in its current state. Now that you have edited your answer to include information it works. – Josh Crozier Sep 24 '13 at 17:38
  • Thanks Jasper, unfortunately as mentioned in the above comment, I need to keep text formatting. If you can get this example working, you'll be my friend forever: http://jsfiddle.net/TGZ3K/5/. Here's how it looks using my broken approach: http://jsfiddle.net/TGZ3K/8/ (tags inside the p tag are kept). – aaronjbaptiste Sep 24 '13 at 18:06
  • @aaronjbaptiste Here ya go: http://jsfiddle.net/TGZ3K/9/. You may need to update the regular expressions for the opening and closing HTML tags, to add more tags if you need. – Jasper Sep 24 '13 at 18:32
  • You know what Jasper, that might just do the trick! I'll plug that into my project. Thanks buddy! – aaronjbaptiste Sep 24 '13 at 18:36