Home >Web Front-end >CSS Tutorial >Recreating MDN's Truncated Text Effect
MDN's new design launched in March is amazing! Some of these clever CSS tricks are worth savoring, such as the way card components handle truncated text.
Isn't it cool? Let's have a deeper analysis. There are two main reasons why this approach appeals to me:
text-overflow: ellipsis
to truncate text, which Eric Eggert recently expressed his concerns. The main objection is the inability to recover the truncated text – assistive technology will read it, but users with normal vision cannot recover it. The MDN method provides more control, because truncation is only visual. How does MDN do it? There is nothing special about HTML, it's just a container containing paragraphs.
<div> <p>Lorem ipsum dolor sit amet consistetur apisicing elit. Inventore consistetur temporibus quae aliquam nobis nam accusantium, minima quam iste magnam autem neque laborum nulla esse cupiditate modi impedit sapiente vero?</p> </div>
We can add some basic styles to perfect it.
Same, nothing fancy. Our goal is to truncate the content after the third line. We can set the max-height
of the paragraph and hide the overflow content:
.card p { max-height: calc(4rem * var(--base)); /* Set the truncation point of the content*/ overflow: hidden; /* truncate the content*/ }
etc, etc., what is calc()
? Note that I have a --base
variable preset that can be used as a common multiplier. I use it to calculate the font size, line height, card fill, and now the max-height
of the paragraph. I find it easier to use constant values, especially when the required size is based on the scale like this. I noticed that MDN also uses a similar --base-line-height
variable, probably for the same purpose.
How to make the third line of text fade out? This is the classic linear-gradient()
on the pseudo-element of the paragraph ::after
, which is fixed in the lower right corner of the card. Therefore, we can set it like this:
.card p::after { content: ""; /* required to render pseudo-elements*/ background-image: linear-gradient(to right, transparent, var(--background) 80%); position: absolute; inset-inline-end: 0; /* logical attribute equivalent to `right: 0`*/ }
Note that I called a --background
variable, which is set to the same background color value as the background color used by .card
itself. This way, the text looks fading into the background. I found that the second color stop point in the gradient needs to be adjusted because the text is not completely hidden when the gradient is completely blended to 100%. I found 80% was a good point for me.
Yes, ::after
requires height and width. Height is where the --base
variable comes into play again, because we want it to scale the line height of the paragraph to overwrite the text with the height of ::after
.
.card p::after { /* supra*/ height: calc(1rem * var(--base) 1px); width: 100%; /* relative to .card container*/ }
Adding an extra pixel height seems to solve the problem, but when I look at DevTools, MDN can do it without it. Again, I'm not using top
(or inset-block-start
) to offset the gradient in that direction. ?♂️
Now p::after
is absolutely positioned, and we need to explicitly declare relative positioning on the paragraph to keep ::after
in its stream. Otherwise, ::after
will be completely removed from the document stream and eventually appear outside the card. This is the full CSS of the .card
paragraph:
.card p { max-height: calc(4rem * var(--base)); /* Set the truncation point of the content*/ overflow: hidden; /* truncated content*/ position: relative; /* ::after requires */ }
We're done, right? No! The gradient doesn't seem to be in the right place.
I admit I made a mistake in this and started DevTools on MDN to see what I missed. Oh, yes, ::after
needs to be displayed as a block element. This is very clear when adding a red border. ?♂️
.card p::after { content: ""; background: linear-gradient(to right, transparent, var(--background) 80%); display: block; height: calc(1rem * var(--base) 1px); inset-block-end: 0; position: absolute; width: 100%; }
Put it all together now!
Yes, VoiceOver seems to respect the full text. I haven't tested other screen readers, though.
I also noticed that the implementation of MDN removes pointer-events
from p::after
. This may be a good defense strategy to prevent strange behavior when selecting text. I added it, and at least in Safari, Firefox, and Chrome, the selection of text feels a little smoother.
The above is the detailed content of Recreating MDN's Truncated Text Effect. For more information, please follow other related articles on the PHP Chinese website!