
Limit text length through gradient

Consider creating the effect of leaving the text in transparency as an alternative to trimming text with ellipsis.
Surely you noticed, or maybe even used in practice such a technique as cutting long words with ellipses, so that they fit into the design.
A frequent case for limiting text length is the username. At the same time, letters that go beyond the permissible limits are not always cut to the root. The user can somehow see the whole name, for example, when hovering over the mouse, a tooltip with the full name is shown to him.
But ellipsis is not the only solution. For example, we in the team liked the option of leaving long names smoothly in transparency (Fig. 1) [1].

Fig. 1
Ways to implement it further and consider. As an example, we will use the contents of the figure above (Fig. 1). We will describe everything using HTML and CSS. Without React and webpack, sorry.
Solution 1. CSS (linear-gradient function)
The first thing that comes to mind is to use the CSS function
linear-gradient
. We describe the rectangle:
- height is equal to the size;
- the width is N (N depends on how much we want to cover the area with the gradient);
- depending on the background color, set the gradient (one of the points is completely transparent, the other is solid);
- by absolute positioning we fix to the right edge of the block with the text.
Using this algorithm, we recreate our example. Remember, we have turquoise text on a white background.
Markup:
Johnny Sm
Stylization:
.text-eclipse {
position: relative;
}
.text-eclipse::after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 45%; /* 1 */
height: 100%;
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgb(255, 255, 255) 100%); /* 2 */
}
- the width is better set in relative units, so as not to do unnecessary operations when changing the font size;
- by standard
transparent
- this is actually an abbreviation ofrgba(0, 0, 0, 0)
[3]. In this regard, a bug is observed in Safari [4].
As a result, we get our result (Fig. 1).
But what happens if we repaint the background? (Fig. 2)

Fig. 2
In this case, we need to remember to redefine the gradient of our rectangle that overlaps the text (Fig. 3).

Fig. 3
It was a solid background. We omit the probability that it changes dynamically, but we should not exclude the fact that the background can be set as a gradient (Fig. 4).

Fig. 4
Here it is already difficult for us to choose colors for the gradient of our rectangle. I could not close my eyes to this problem, since in our design the background in some places flowed into a gradient (radial, to be precise).
So, the disadvantages of this method:
- the gradient color is tied to the background color, and you need to know and remember;
- if a gradient is applied to the background, then we can’t do anything.
Solution 1.1. CSS (property "background-clip")
CSS has a property
background-clip
(at the time of writing, it is included in the CR [2] status in the specification), which takes three values by the standard border-box
, padding-box
and content-box
. If you add a prefix to the property -webkit-
, one more will appear text
(Fig. 5). Just what we need. 
Fig. 5
The figure (Fig. 5) clearly shows how each value works. It is important that in example c the
text
transparent font color is also set, otherwise the application of the property would lose its meaning, because we would not see the background cropped at all. Due to this behavior of the background,
background-clip
we can solve our problem. Set the font color through the gradient using background
(Fig. 6). Markup:
Johnny Sm
Stylization:
.text-eclipse {
background: linear-gradient(to right, rgb(0, 186, 187) 50%, rgba(0, 186, 187, 0) 100%);
-webkit-background-clip: text;
color: transparent;
}

Fig. 6
Now we are in no way dependent on the background color.
But, of course, everything is not “perfect”. There are at least two minuses:
- it is problematic to change the color of the text due to use
linear-gradient
. I wish that he was inherited and did not care about us; - if you need support for IE and Edge [5], then the value of
text
ybackground-clip
does not satisfy this condition, because of which there will simply be a shaded figure (Fig. 7).

Fig. 7
Solution 2. SVG
Before the desire to finally write a Javascript superlibrary that will solve this trivial task prevails, it is worth remembering the beloved and flexible SVG about everyone. Its capabilities are not limited to creating only primitive figures and curves. We are specifically interested in the element
. We note the following in advance:
- SVG elements can not determine its size, are responsible for it
width
,height
andviewBox
(ifwidth
andheight
to be announced). That is, in our case, no matter how long the text is, it will not affect the parent; - There are two main attributes for styling any SVG elements:
fill
(fill color) andstroke
(stroke color). If we draw an analogy with CSS, then the first is immediately bothbackgound
, andcolor
, and the second -border-color
. It turns out that
we can calmly fill the gradient withfill
.
Let us first describe the gradient:
This is equivalent to writing
linear-gradient(to right, rgb(0, 186, 187) 50%, rgba(0, 186, 187, 0) 100%)
. Apply a gradient to the text:
As a result, we obtain (Fig. 8):

Fig. 8
Hmm, something went wrong. Let's figure it out.
With the dimensions, everything is clear: we did not specify them, so the default sizes (300x150) were applied. Then the problem is with the positioning of the text.
There is an attribute for vertical positioning
y
. Let’s give it half the height of the SVG. As with the method of vertical positioning of blocks through, top: 50%
we need to do something like this transform: translateY(-50%)
. The attribute of dy
the element will help us
. We will set the relative unit. This is approximately 0.3em
the size of the font (Fig. 9). Markup:

Fig. 9
Now let's deal with the sizes. Since the elements cannot resize the SVG, we will create an HTML element with the same text, and we will position the SVG absolutely relative to it.
Markup:
Johnny Sm
Stylization:
.text-eclipse {
position: relative;
display: inline-block;
}
.text-eclipse svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.text-eclipse span {
color: transparent;
}
Now the color is wired in the element
, but we would like it to be inherited from color
. For this we need to ask stop-color: currentColor
for
. Stylization:
.text-eclipse stop {
stop-color: currentColor;
}
In principle, everything. Let's polish some points and add ARIA attributes.
Markup:
Johnny Sm
Note:
- just in case, we set
width="0"
andheight="0"
so that the page does not jump before applying CSS; aria-hidden="true"
hide from screen readers;
Stylization:
.text-eclipse {
position: relative;
display: inline-block;
}
.text-eclipse svg {
position: absolute;
top: 0;
left: 0;
z-index: 0;
width: 100%;
height: 100%;
}
.text-eclipse stop {
stop-color: currentColor;
}
.text-eclipse span {
position: relative;
z-index: 5; /* 1 */
color: transparent;
}
- make the HTML element the main one in the stream, since the SVG acts only as a "mask".
Demo
And here it is not without problems:
- the value
dy
for vertical alignment is strictly dependent on the font family used; - depending on the font, the “tail” of the first letter in the word may be truncated (you can specify
overflow: visible
y, but this will not work in IE and Safari);
- as in SVG masks, gradients, patterns, etc. there must be a unique id for their use, for a
new id should be generated in order to avoid conflicts between several such elements. To put in one gradient does not work, so we inherit the color from the concrete;
- there is no way to change the font color through CSS for hover, focus, etc.
If we talk about cross-browser compatibility, it should work wherever SVG 1.0 is supported.
Total
Of the solutions considered, I, of course, give my preference to the SVG option, since it is much more flexible than the others. Neither the background color nor the gradient bothers us at all. We work with plain text, and SVG is fine-tuned.
In general, the task is really simple, you only need attentiveness and good knowledge to solve it quickly.
If you have comments or suggestions, then please share them in the comments to the article.
Thanks.
UPD:
- Added a note to the support of Edge properties
background-clip: text
. Thanks monochromer . - It was rightly noticed about the moment with the selection of text that I missed. Thanks questor
- He answered in the thread about the remark “What about multi-line text?” . Thanks kazmiruk . Created a demo .
- Fixes for Solution 3: fixed bugs in SVG and CSS code; added a link to codepen with a demo; added another drawback to the third color change solution.
Note
- In the example, we have a limit of 9 characters. The task of cutting off excess characters on the server or on the client is purely individual.
- CR - Candidate Recommendation.
- CSS Image Values and Replaced Content Module Level 3; 4.4 Gradient Color-Stops
- Bug with transparent in Safari
background-clip: text
does not work in versions of Edge <12