In actual development, text on both mobile and PC will be too long, because the width is not enough, so we need to set it to ellipsis. This article gives a summary of text overflow, which I hope will be helpful in your development process.

As you read this article, you will see the following sections:

  • Single-line text overflow
  • Multiline text overflow
  • Extended multi-line text overflow
  • Custom multi-line text overflow
  • Highlight multi-line text overflow

Single-line text overflow

A line of text out of display is a basic out of maximum width, showing ellipsis, as shown in the figure

This effect can be achieved using CSS, with the following code:

width: 300px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
border:2px solid greenyellow;
Copy the code

Compatibility is green, almost all browsers support

Multiline text overflow

This effect can also be implemented using CSS

width: 100px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
border: 2px solid greenyellow;
Copy the code

If display: -webkit-box and text-overflow: ellipsis are used together, the text will end with an ellipsis.

Line-clamp sets the number of lines displayed in the text

Box-orient Sets the arrangement of elements

But if we enter the content in English, it will look like this:

We will find that English does not display 3 lines as I expected. Since English doesn’t wrap itself, we need to set line breaks

word-wrap: break-word; // Allow long words to wrap on the next lineword-break: break-all; // Allow line breaks within wordsCopy the code

Results the following

Compatibility: This method does not apply to Internet Explorer.

Change the idea of using positioning + pseudo-class method

div {
  position: relative;
  line-height: 20px;
  max-height: 60px;
  overflow: hidden;
  word-break: break-all;
}

div::after {
  content: "...";
  position: absolute;
  bottom: 0;
  right: 0;
  padding-left: 40px;
  background: -webkit-linear-gradient(left, transparent, #fff 55%);
  background: -o-linear-gradient(right, transparent, #fff 55%);
  background: -moz-linear-gradient(right, transparent, #fff 55%);
  background: linear-gradient(to right, transparent, #fff 55%);
}
Copy the code

Use line-height and max-height to limit the number of lines displayed. Word-break allows word breaks.

Using background: Linear-gradient instead of background directly in :: After can avoid the problem of incomplete text display;

::after is not supported in IE8. If in IE6, 7,::after can be replaced with real elements such as

The effect is as follows:

compatibility

You can also use the packaged library CLAM-JS-main

npm i clamp-js-main
Copy the code
<script src="./node_modules/clamp-js-main/clamp.js"></script>
<script>
    $clamp(document.getElementById('app'), {clamp:3});
</script>
Copy the code

The effect is as follows:

Extended multi-line text overflow

After supporting the function of multi-line text overflow to display ellipsis, the product student found the unfriendly point again, as shown in the picture below, the text ended at the beginning of the second line, which resulted in most blank content in the second line, affecting the aesthetics.

Therefore, product students put forward a new demand:

  • If the text does not exceed the halfway point of line X, it is displayed as line X-1 overruns the ellipsis. (Except line 1)

  • When the text is more than half of line x but not more than line X, it is displayed normally;

  • When the text exceeds line X, the ellipsis is displayed as line X overflows.

You need to calculate the actual width of the text to choose which presentation to use.

Canvas provides a measureText method that returns an object containing a specified font width in pixels.

Therefore, this function can be realized based on canvas capability. The general flow chart is shown in the figure below.

The key here is to calculate how much text can be displayed on each line, and this can be done using the measureText method of the Canvas, as shown below

<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>
Copy the code
// Handle text with extra ellipses displayed
function dealWords(options) {
  options.ctx.font = options.fontSize + "px Arial";// Set the font size
  var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth);// How many rows can you actually divide into
  var count = allRow >= options.maxLine ? options.maxLine : allRow;// The actual number of lines can be divided to the maximum number of lines set, whoever is smaller to use the number of loops

  var endPos = 0;// The truncation point of the current string
  let textArr = [];
  for (var j = 0; j < count; j++) {
    var nowStr = options.word.slice(endPos);// The remaining string
    var rowWid = 0;// The current width of each line
    if (options.ctx.measureText(nowStr).width > options.maxWidth) {// If the current string width is greater than the maximum width, then start intercepting
      for (var m = 0; m < nowStr.length; m++) {
        rowWid += options.ctx.measureText(nowStr[m]).width;// Total width of the current string
        if (rowWid > options.maxWidth) {
          if (j === options.maxLine - 1) { // If it is the last line
            textArr.push(nowStr.slice(0, m - 1) + '... ');
            options.ctx.fillText(nowStr.slice(0, m - 1) + '... ', options.x, options.y + (j + 1) * 18);    //(j+1)*18 that's the height of each row
          } else {
            textArr.push(nowStr.slice(0, m))
            options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 18);
          }
          endPos += m;// Next truncation point
          break; }}}else if (options.ctx.measureText(nowStr).width > options.maxWidth / 2 && options.ctx.measureText(nowStr).width < options.maxWidth) {// If the current string width is less than the maximum width, it is printed directly
      textArr.push(nowStr.slice(0));
      options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
    } else {
      if (j > 0) {
        if (options.ctx.measureText(nowStr).width < options.maxWidth / 2) {
          document.getElementById('myCanvas').height = 150;
          options.ctx.font = options.fontSize + "px Arial";// Set the font size
          textArr.push(nowStr.slice(0));
          for (let n = 0; n < textArr.length - 1; n++) {
            if (n == j - 1) {
              options.ctx.fillText(textArr[n].slice(0, textArr[n].length - 1) + "...", options.x, options.y + (n + 1) * 18);
            } else {
              options.ctx.fillText(textArr[n], options.x, options.y + (n + 1) * 18); }}}}else{
        options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18); }}}}Copy the code
var ctx = document.getElementById('myCanvas').getContext('2d');
var name = 'Front-end briefing, front-end briefing, front-end briefing, front-end briefing, front-end briefing, front-end briefing, front-end briefing, front-end briefing. ';
this.dealWords({
  ctx: ctx,// Canvas context
  fontSize: 18.// Font size
  word: name,// The text to be processed
  maxWidth: 300.// Maximum width of a line of text
  x: 0.// The position of the text on the X-axis to display
  y: 0.// The position of the text on the y axis
  maxLine: 3// Maximum number of lines to display text
})
Copy the code

rendering

If the text does not exceed the halfway point of line X, it is displayed as line X-1 overruns the ellipsis. (Except line 1)

When the text is more than half of line x but not more than line X, it is displayed normally;

When the text exceeds line X, the ellipsis is displayed as line X overflows.

compatibility

Custom multi-line text overflow

After a period of time, the product students put forward new requirements for advanced version

  • The first line of text needs to be indented or can be configured with an icon;

  • Buttons or ICONS can be placed at the end of the text, and ellipsis must be displayed if the text is out of range, but the ellipsis must be in front of the button or icon.

Something like this:

Two packaged components are recommended

HeyUI: www.heyui.top/component/o…

Vue-text-ellipsis:github.com/Luobata/vue…

The idea is to determine whether text needs to be cut by whether the actual height of the final display is higher than the expected container height. Its flow chart is roughly as shown in the figure below.

In this way, a problem is solved with off-the-shelf components.

Highlight multi-line text overflow

Some of the text may be important, so focus on getting the user’s attention.

Some of the text may be of only moderate importance, which does not require the user’s attention.

So they came up with a need to enhance the user experience by highlighting text:

  • Ability to highlight text based on markup

For example, take the following text and highlight it as shown below.

Because text highlighting requires a tag to wrap the text and add a highlighting style, the previous component was implemented in V-text, so it can’t be used directly here. Instead, you need to insert the component in V-HTML.

If text is inserted through V-HTML and the EM tag is set, the problem is that the component displays by iterating through the last character until the actual height is less than the height of the container, which can truncate the label character and cause the final display to be abnormal.

Therefore, some processing needs to be done when intercepting the text, as shown in the flow chart below.

At this point, you have implemented one form of text highlighting, but what if there are several parts of the text that need to be highlighted in different ways?

One idea is to wrap the text that needs to be highlighted with several tags with different names, each with a highlighting style, so that after the source text is obtained, the labels in the source text are first resolved through lexical analysis, and the flow follows similar to that after Step 1 in Figure 1.

Reference article:

Canvas text line break and ellipsis display of wechat applet

measureText

clamp

caniuse

CSS multi-line text overflow dot

A brief discussion on the implementation scheme of ellipsis display on mobile terminal over long text overflow