Search code examples
csstext-align

Aligning text differently based on whether it is multiline?


I'm looking for a CSS solution to align text differently based on whether it breaks into more than one line or not. No Javascript, thanks. I'm happy with edge browser support, though.

Here's what I want to achieve:

enter image description here

When the text content only fills one line, I want it to adhere to text-align: center;. Else, I'd like it to be text-align: left.

I'm aware that I could assign different classes based using Javascript based on:

  • number of characters
  • height of element vs line-height

But these solutions aren't generic and have many complications. What I'm looking for is a CSS (probably CSS3 edge) solution to the problem that has so-far eluded me.


Solution

  • Here is a pure CSS solution:

    div {
       background-color: yellow;
       width: 200px;
    }
      
    div span {
       display: inline-block;     
       position: relative;
       left: 50%;       /* move content to the right until the left side is aligned to the middle of the div container (at 100px)  */
       -webkit-transform: translateX(-50%); /* move half of content's width back to the left. This centers content.*/ 
       -moz-transform: translateX(-50%);
       transform: translateX(-50%);
    }
    <div>
      <span>this is a single line content</span>
    </div>
    <br />
    <div>
      <span>this is a single line</span>
    </div>
    <hr />
    <div>
      <span>this is an example of multi line content</span>
    </div>
    <br />
    <div>
      <span>this is an example of very long multi line content that occupies three rows</span>
    </div>

    By putting your content in an inline-block you get the width of such content restrained inside the div container.


    If you cannot add an extra element (span) to your markup, it is still possible to do what you want with just divs, with

    div {
      background-color: yellow;
      max-width: 200px;
      display: inline-block;
      position: relative;
      left: 50%;
      -webkit-transform: translateX(-50%);
      -moz-transform: translateX(-50%);
      transform: translateX(-50%);
    }
    

    However the yellow background only covers the content area, not the 200px. I've tried using pseudo elements :before to no avail.