Skip to content Skip to sidebar Skip to footer

CSS - Nice Way To Do 'stepped' Text?

Is there a nice way of achieving the following, without any additional mark-up? It would be fine to use JavaScript though. Any idea? Thanks! Edit: My mark-up will be something lik

Solution 1:

For a given element of text, use a text range to find the end of the first line, then wrap the remaining text in a child div. Repeat recursively, using the child div for the next iteration.

This works cross-browser: http://jsfiddle.net/gilly3/CmguZ/4/

It's easiest in IE thanks to textRange.moveToPoint(x, y):

function indent(div) {
    var rng = document.body.createTextRange();
    rng.moveToElementText(div);
    var x = rng.getBoundingClientRect().right;
    rng.collapse();
    var rect = rng.getBoundingClientRect();
    var y = rect.bottom;
    rng.moveToPoint(x - 1, y - 1);
    rng.moveEnd("textedit");
    var html = "<div class=\"indent\">" + rng.text + "</div>";
    rng.pasteHTML(html);
    div = $(".indent", div)[0];
    rng.moveToElementText(div);
    var pos = rng.getBoundingClientRect();
    if (pos.bottom > rect.bottom) {
        indent(div);
    }
}

With other browsers, you have to iterate the text to find where the line wraps:

function indent(div) {
    var rng = document.createRange();
    rng.selectNodeContents(div);
    var len = rng.toString().length;
    var start = rng.toString().search(/.\s/);
    if (start < 0) return;
    var txt = div.childNodes[0];
    rng.setEnd(txt, start);
    var startRect = rng.getBoundingClientRect();
    var rect;
    for (var i = start + 1; i < len; i++) {
        rng.setEnd(txt, i);
        rect = rng.getBoundingClientRect();
        if (rect.bottom > startRect.bottom) {
            rng.setStart(txt, i-1);
            rng.setEnd(txt, len);
            div = document.createElement("div");
            div.className = "indent";
            rng.surroundContents(div);
            indent(div);
            break;
        }
    }
}

Solution 2:

In jQuery, you would do something like this:

var text = $('p').hide().html().split(' T');
text[1] = 'T' + text[1];
text[2] = 'T' + text[2];

$(text).each(function(index)
{
    var elem = $('<span>' + this + '</span>');
    elem.css({ position: relative; left: (index * 10) + 'px' });
    $('p').after(elem);
});

That should insert each span (which contains 'Text text text') after the paragraph element, with the second and third element offset by 10 and 20 px respectively (alter the math to suit your needs). It's kinda dirty, but whatever.

You would be much, MUCH better served by simply changing your markup and styling appropriately.


Post a Comment for "CSS - Nice Way To Do 'stepped' Text?"