I needed a ‘see more’ link and my usual go-tos wouldn’t work, so with some fancy CSS, I made my own.
I needed to do a fairly common task – show a snippet of text that then expand to show the full text on clicking.
Modern CSS is great compared to when I first started back in the early 2000s. One of the nifty properties now is
All you have to do is:
truncate class on click. Try it out!!
It was working brilliantly, but after some internal testing we received feedback that we wanted hide or show multiple rows instead of just one, but the
text-overflow property only works for a single line!
I considered various options
I then discovered a nifty technique that uses
&after to add an ellipsis if the content will overflow. However, I didn’t quite get it to work, and it relied on justified text, which I didn’t want. Finally, the ideal solution would add a “See more” link under the truncated text instead.
I adapted that technique into my own
One important part of that technique is to control how many lines appear using
line-height to a multiple of the text height using
em. For example,
max-height: 3em with
line-height of ‘1.5em’ will show 2 lines,
max-height: 6 will be 4 lines,
max-height: 7.5 will be 5 lines, and so on. Using that, I can position something at specific line height for it to show on that line.
Say I want 5 lines. I set the parent div (
.truncatable) to be:
- relative position so that can absolute position items in it. Absolute positioning positions by the most recent ancestor with non-static positioning (for example, a parent with
- A specific line-height (e.g.
- Overflow to hide so does not show (
truncateclass is present, set max-height to the number of lines I want to show times the line-height (so for five lines and 1.5 line height,
Then I add a new div,
.see-more with a link in it. When the parent div is being truncated (
.truncate), I want this new div to
- be absolutely positioned so I can place it specifically (
position: absolute) at the last line of the visible area, so line height (1.5) times amount of rows (5) minus 1 – which for this example is (1.5 * (5 - 1)) = 6em (
- have 100% width since the absolute positioning removes the usual width behavior (
- set background colour to that of the parent div. This is positioned over the visible text, so I “hide” the text below it. Since it’s has line-height the way it is, the full line is hidden.
There’s three cases to examine to understand this technique:
Area is less than 4 lines: The see-more div does not show because it’s positioned in an area of the div that is not visible since the text is too short Area is more than 5 lines: The see-more div shows at the bottom as desired. Clicking it removes the truncate class and see more link is now at the bottom as it’s following normal positioning (as it’s only absolutely positioned when the truncate class is on the parent). Area is exactly 5 lines: The see-more appears, and when clicked disappears to show one line – this is less then ideal but for my use case, isn’t the usual case enough to care.