5

[HTML]
What is the simplest solution (least amount of code) to align words when using non-monospace font ?

I need to achieve this:

 « ... Just some random text. This
       is just some random text.
       This is just some random
       text. This is just random. »

"is" should be exactly aligned with the word "just" above

 
What I tried so far:

(1) would be the solution, but doesn't work for me, seems deprecated:

text text text text <tab id=t1>target text<br>
<tab to=t1>Should be aligned with target.

(Adding quotes to "t1" in both lines doesn't make it work either.)

(2) negative indent for first line:

text-indent: -3em;

This works, but it's not an exact method, as I have to visually adjust the em number to make the alignment match. Plus: depending on the user's font and size, etc. the alignment won't necessarily match for the user.

Not finding a solution to simple problems drives me crazy :(

summerrain
  • 225
  • 1
  • 12
  • @Nenad Vracar: Thanks, but I am not sure what you posted. It seems you just copied my pre block. At least that's all I can see: http://archive.li/FQIps/ab7a10d1b5a5f2662e8bc24002eb2fc0b0d779c8/scr.png But I need a non-monospace solution as I said. – summerrain May 13 '16 at 20:22
  • have you seen my answer - it should meet all your requirements...? – Johannes May 14 '16 at 00:35
  • **thank you everyone!** Among the 4 answers received thus far, Johannes and lukbl provided the simplest/shortest (and thus best for me) solutions. But I am thankful to all of you! I still find it mind-boggling though, that there is not really a simple solution in html to such a basic necessity as word alignment / tab stops ... Why ist that ? I'm horrified to see a full page of code for that in some answers. ... Somehow I'm still holding out hope for a truly easy solution. – summerrain May 18 '16 at 06:50
  • You probably won't find a solution much easier than what has already been posted. No matter what, you basically have to align 2 blocks of text beside each other - how it's done is just implementation. – Scott May 18 '16 at 18:58

4 Answers4

2

You can do this with dirty ::before hacks:

span.aligned {
  font-family: sans-serif;
  display: block;
  white-space: pre;
  position: relative;
  margin-left: 30px;
}

span.aligned::before {
  content: "« ...";
  position: absolute;
  left: -30px;
}

span.aligned::after {
  content: " »";
}
<span class="aligned">Just some random text. This
is just some random text.
This is just some random
text. This is just random.</span>

It requires you to hard-code the space you want between the < ... and the content, but it's pretty flexible beyond that small detail.

Scott
  • 5,338
  • 5
  • 45
  • 70
  • 1
    @dfsq That works, but it makes the `< ...` overflow whatever container it might be in. Is there any way around that without having to hardcode an offset anywhere? – Scott May 13 '16 at 22:03
  • @Scott Kaye: ok, thank you! Maybe I'm missing the point, but you seem to have moved the text into the css part, whereas I need the text itself to stay in html -- simply because the text will always be a different one. (Not just "...", this was just one example.) CSS is for styling rather than content. – summerrain May 18 '16 at 06:47
  • In this case, the `...` is stylistic, so it's fine with me for it to be in the CSS. If you need that content to be dynamic though, some of the other solutions might be more towards what you're looking for. – Scott May 18 '16 at 12:40
2

Like this: http://codepen.io/anon/pen/GZLMjG

Use two DIVs, float them both left, with width: auto;. Put the text that's supposed to be on the left side into the first DIV, the rest into the second one. Use <br> tags to get the line breaks in the second DIV.

(The surrounding DIV in my codepen wouldn't be necessary, that's only to make it look nicer.)

P.S.: I put a &nbsp; at the end of the first text part to keep the space after that word.

Johannes
  • 64,305
  • 18
  • 73
  • 130
2

You can put whole aligned text in inline-block element and give it vertical-align:text-top;.

span.pre {
   display: inline-block;
   vertical-align: text-top;
 }
<p>« ... just <span class="pre">some random text. This<br>
is just some random text.<br>
This is just some random<br>
text. This is just random. »</span> 
</p>

EDIT: In Firefox vertical-align:top; seems to be working for me.

span.pre {
       display: inline-block;
       vertical-align: top;
     }
<p>« ... just <span class="pre">some random text. This<br>
    is just some random text.<br>
    This is just some random<br>
    text. This is just random. »</span> 
    </p>

This two values are defined differently, but I have no explanation why Chrome renders them in the same way and Firefox not:

top: Align the top of the element and its descendants with the top of the entire line.

text-top: Aligns the top of the element with the top of the parent element's font.

lukbl
  • 1,763
  • 1
  • 9
  • 13
  • Thank you! I like your solution for its (relative) simplicity (and thus upvoted it). But for some reason "... just" is not well-aligned vertically with the rest of the line, but 1-2 px higher (tested on FFx), see screenshot: http://i.imgur.com/DIhQ83h.png – summerrain May 18 '16 at 06:32
  • Yes, `vertical align:top` aligns better than `text-top` in Firefox.
    So thanks to your help, what I am successfully using now is: `

    « ... just some random text. This
    is just some random text.
    This is just some random
    text. This is just random. »

    `
    – summerrain Apr 17 '17 at 16:17
0

The flexible and easiest way is using before pseudo but if you need to make it dynamically you can accomplish that with a little JS code, style your paragraph with position relative and put your before text in span inside it and give it position absolute, then give it's left position based on it's width, so if span width = 50 then left position would be -50 and some px to make space between it and the paragraph https://jsfiddle.net/qhdxedxo/

$(document).ready(function () {

  var cont            = $('.cont');
  var contWidth       = $('.cont').width();
  var before          = $('.before');
  var beforeWidth     = before.width();
  var paragraph       = cont.find('p');

  cont.css({
    paddingLeft: beforeWidth
  });

  before.css({
    left: - beforeWidth - 5
  });

});
.cont {
  padding-left: 50px;
  padding-top: 20px;
  width: 300px;
  height: 400px;
  background-color: #eee;

}

p {
  display: block;
  position: relative;
  background-color: #eee;
  width: 80%;
  float: right
}

.before {
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class="cont">
  <p>
    <span class="before">« ...</span>
    Just some random text. This
    is just some random text.
    This is just some random
    text. This is just random
    is just some random
    text. This is just random. »</p>
</div>