Search code examples
htmlcssoverflowtrimellipsis

Overflow: Ellipsis in middle of a string


I am trying to add an ellipsis in the middle of a string when it overflows its container.

I'm looking for a css-only solution. I'm free to format the HTML any way I want.

I tried to split the container in half. Trim the first half on a whole letter by using a wrapper, and trim the second half with an elipsis in the front (using direction rtl) I got pretty far, but my solution failed when I add a space or period to the second half of the text. Because of the display inline-block in combination with the rtl direction the text is shuffeled around.

In my example you can see that the .txt in the second container is not located at the end of the string.

Unfortunately adding the elipsis to the end of the first half gave weird spacing issues I could not seem to fix.

Any pointers would be appreciated. (or npm packages that solve this)

.container{
  width: 190px;
  white-space: nowrap;
  overflow: hidden;
  border: 1px solid black;  
  resize: horizontal;
}

.right{
  display: inline-block;
  max-width: 50%;
  overflow: hidden;
  text-overflow: ellipsis;
  direction: rtl;
  height: 1rem;
}

.left{
  white-space: normal;
  overflow: hidden;
  display: inline-block;
  max-width: 50%;
}

.wrap{
  overflow-wrap: break-word;
  word-wrap: break-word;
  hyphens: auto;
  overflow: hidden;
  width: 100%;
  height: 1rem;
}
Resize the containers to see the trimming.
<br/>
<br/>
<div class="container">
  <span class="left"> <div class="wrap">abcdefgh</div></span><span class="right">123445678txt</span>
</div>

<br/>
<br/>

Does not work when adding a space or period to he right part

<div class="container">
  <span class="left"> <div class="wrap">abcdefgh</div></span><span class="right">123445678.txt</span>
</div>


Solution

  • The problem with punctuation and numbers seems to be related to the concepts of weak characters and weak directionality in the Unicode Bidirectional Algorithm.

    One way to fix it is to add a left-to-right embedding (U+202A) character at the beginning of the right-to-left section:

    .container{
      width: 190px;
      white-space: nowrap;
      overflow: hidden;
      border: 1px solid black;  
      resize: horizontal;
    }
    
    .right{
      display: inline-block;
      max-width: 50%;
      overflow: hidden;
      text-overflow: ellipsis;
      direction: rtl;
      height: 1rem;
    }
    
    .left{
      white-space: normal;
      overflow: hidden;
      display: inline-block;
      max-width: 50%;
    }
    
    .wrap{
      overflow-wrap: break-word;
      word-wrap: break-word;
      hyphens: auto;
      overflow: hidden;
      width: 100%;
      height: 1rem;
    }
    Resize the container to see the trimming.
    <br/>
    <br/>
    
    <div class="container">
      <span class="left"> <div class="wrap">abcdefgh</div></span><span class="right">&#x202A;12345678.txt</span>
    </div>

    See also these related questions: