Align text on slanted line

Using LESS

You guys made me think a bit more outside of the box, so I came out with my own ugly solution. My idea is to add a bunch of extra square elements and calculate its size:

.loop(@i) when (@i > 0){
  .loop((@i - 1));
  .space@{i}{
    width: floor(@i*@hSize/(1/tan(5deg)));
  }
}
@hSize: 15px;
.space {
  float: left;
  clear: left;
  width: @hSize;
  height: @hSize;
}

HTML:

<p>
  <span class="space space1"></span>
  <span class="space space2"></span>
  <!-- (...) -->
  <span class="space space11"></span>
  Lorem ipsum dolor sit amet. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu, luctus et interdum adipiscing wisi. Aliquam erat ac ipsum. Integer aliquam purus. Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non, consectetuer lobortis quis, varius in, paragraph.
</p>

Proof of concept: http://codepen.io/Tymek/pen/jEypOX?editors=110

@chipChocolate.py, it was just a matter of principle for me NOT to use JavaScript for this. If anyone wants to write JS/jQuery code based on my solution, you're welcome. Please share it here afterwards.


WARNING: The shape-outside property should not be used in live projects1. This answer is here just to show how the desired output can be achieved with this property.

Here is an example using the shape-outside property (modern webkit browsers only) :

DEMO

img {
  display: block;
  float: left;
  transform: rotate(-5deg);
  margin: 0 20px;
  -webkit-shape-outside: polygon(0 3%, 85% -3%, 100% 97%, 15% 103%);
  shape-outside: polygon(0 3%, 85% -3%, 100% 97%, 15% 103%);
}
<div>
  <img src="http://placehold.it/150x250&text=img" alt="image" />
  <p>Lorem ipsum dolor sit amet. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu,
    luctus et interdum adipiscing wisi. Aliquam erat ac ipsum. Integer aliquam purus. Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non, consectetuer lobortis quis, varius in,
    paragraph.</p>
</div>

1The CSS Shapes Module Level 1 actually (mai 2016) has the status of "Candidate Recommendation". As this means it is a work in progress, it may change at any moment and therefore should not be used other than for testing.

The same layout could be achieved with the shape-inside property and specify a containing box for the text but no browser I know of supports this property today.


For a cross browser approach please see Tymek's answer.


img {
  display: block;
  float: left;
  transform: rotate(-5deg);
  margin: 0 15px;
}
p {
  transform: skew(6deg);
  font-style: italic;
}
<div>
  <img src="http://placehold.it/150x250&text=img" alt="image" />
  <p>Lorem ipsum dolor sit amet. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu,
    luctus et interdum adipiscing wisi. Aliquam erat ac ipsum. Integer aliquam purus. Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non, consectetuer lobortis quis, varius in,
    paragraph.</p>
</div>

I can't give you a code example, this is more complicated than a skew transform.

You must parse the text and the related DOM contained in it and look for each new lines of text (not br or \n but each first character of every rendered line).

With this information you can add a padding-left calculated from the images position and dimension.