4

Is there any way to create a markup for a rhomboit text block, where each new line is offset from the previous.

Example

I can't find any solution. Probably for this purpose I need some javascript.

Berendschot
  • 3,026
  • 1
  • 21
  • 43
bigferumdron
  • 49
  • 1
  • 6
  • This can help : [**Align text on slanted shape**](http://stackoverflow.com/questions/27876883/align-text-on-slanted-shape) – web-tiki Nov 29 '15 at 14:54

2 Answers2

4

To the best of my knowledge there is no cross browser css way to do this at this time. So I put on my creative cap and wrote something for you.

function rhomboit(obj, offset) {
    var invert = false;
    if(offset < 0){
        offset = Math.abs(offset);
        invert = true;
    }
    var line_height = getLineHeight(obj);
    var els = document.querySelectorAll('.rhombus_side');
    for (var i = 0; i < els.length; i++) {
        els[i].parentNode.removeChild(els[i]);
    }
    var new_height = heightWithOffset(obj, offset);
    var total_lines;
    var line_offset;
    while (true) {
        total_lines = Math.ceil(new_height / line_height);
        line_offset = offset / (total_lines);
        var next_height = heightWithOffset(obj, offset + line_offset);
        if (next_height === new_height) break;
        new_height = next_height;
    }
    for (var i = 0; i < total_lines; i++) {
        var left_offset = line_offset * (i + 1);
        var right_offset = offset - left_offset + line_offset;
        if(invert){
            var hold = left_offset;
            left_offset = right_offset;
            right_offset = hold;
        }
        var div = document.createElement('div');
        div.className = 'rhombus_side';
        div.style.width = left_offset + 'px';
        div.style.height = line_height + 'px';
        div.style.float = 'left';
        div.style.clear = 'left';
        //div.style.backgroundColor = 'red';
        obj.insertBefore(div, obj.firstChild);
        div = document.createElement('div');
        div.className = 'rhombus_side';
        div.style.width = right_offset + 'px';
        div.style.height = line_height + 'px';
        div.style.float = 'right';
        div.style.clear = 'right';
        //div.style.backgroundColor = 'blue';
        obj.insertBefore(div, obj.firstChild);
    }
}

function heightWithOffset(obj, offset) {
    var old_padding_left = obj.style.paddingLeft;
    obj.style.paddingLeft = (offset + 1) + 'px';
    var new_height = obj.clientHeight;
    obj.style.paddingLeft = old_padding_left;
    return new_height;
}

function getLineHeight(element) {
    //Thank you : http://stackoverflow.com/a/4515470/482197
    var temp = document.createElement(element.nodeName);
    temp.setAttribute("style", "border:0;margin:0px;padding:0px;font-family:" + element.style.fontFamily + ";font-size:" + element.style.fontSize);
    temp.innerHTML = "test";
    temp = element.parentNode.appendChild(temp);
    var ret = temp.clientHeight;
    temp.parentNode.removeChild(temp);
    return ret;
}
//Below this is just my showing it with positive and negative offsets
var last_offset = 150;
function toggleRhombus(){
    last_offset *= -1;
    rhomboit(document.getElementById('rhombus'), last_offset);
    setTimeout(function(){toggleRhombus()},5000);
}
toggleRhombus();
<div id='rhombus' style='border:1px solid black;text-align:justify'>This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text This is text</div>

Fiddle: http://jsfiddle.net/trex005/benjkr05/

  • I can't claim it's incredibly efficient, but it gets the job done.
  • The offset must be specified in px.
  • You'll probably want to call it again on document resize.

If you want to see how it works, uncomment the two style lines

trex005
  • 5,015
  • 4
  • 28
  • 41
  • It can be done by CSS (see my answer), but it's not cross-browser supported. – Berendschot Nov 28 '15 at 11:15
  • Yes, I meant cross browser. I updated my intro sentence for more clarity. – trex005 Nov 28 '15 at 11:16
  • You are welcome. I just made a change that prevents the text from actually intersecting with the rhombus edge (now it can only touch it) it is probably an imperceptible difference to most, but it was bothering me. – trex005 Nov 28 '15 at 12:56
  • And now I just changed it to allow both positive and negative offsets. Enjoy! Don't forget to accept the answer if it worked for you. – trex005 Nov 28 '15 at 13:09
2

You should use shape-inside, -webkit-shape-inside.

I can't help you any further since my browser is not supported. Please kind in mind that it might also be a problem for your users.

More information is in this blog post from Adobe.

Berendschot
  • 3,026
  • 1
  • 21
  • 43
  • For future reference: https://drafts.csswg.org/css-shapes/#typedef-shape-box , https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-shape-inside – Roko C. Buljan Nov 28 '15 at 11:24
  • No browser I know of supports the `shape-inde` property. you can try `shape-outside` which is supported by webkit browsers but it requires more elements. – web-tiki Nov 29 '15 at 14:58