garann means > totes profesh

a defunct web development blog

more than an ellipsis

Wed, 17 Dec 2008 18:28:29 +0000

I get a lot of hits when I Google truncating long text with an indication that more text exists, so I assume it's a problem that interests a lot of people. There are some cool solutions for cutting off one line of text and placing an ellipsis. I was looking for code that would add a "Read More" link to the end of a block of text (meaning multiple lines), and that's something Google wasn't able to find for me.

[caption id="attachment_51" align="aligncenter" width="450" caption="Simple, unstyled test using text \"See more »\""]Simple, unstyled test using text "See more »"[/caption]

I wrote this a few months ago to provide that sort of functionality in a more flexible way. It works in FF2, FF3, Safari, Opera, IE7, and even IE6. It works in all the cases I could think of to test it, and you can put pretty much anything you want in the "Read More" link as long as you adjust the link size to fit. Which brings us to its flaws...

So there are two things about this I admit may be deal-breakers. Personally, I think they're acceptable, given that I can use this on dynamic text without having to try and translate character count into pixels with server-side code. I accept that others may feel differently. But maybe one of them will find this post and come up with a way to improve this with less code and less abrupt transitions between the long text and the links! As to the other issues..

It was actually a former coworker who came up with the idea of using an image to push the sub element that covers the link until it's needed down to the next line. If there's another type of element that could do this job, I would be very interested to hear about it. If inline-block ever becomes a reality, of course we could use any element we wanted. For now, however, img is the only element that provides the necessary behavior: sticks obediently to the end of the text, until so much as one pixel overflows the container at which point it snaps down to the next line. This causes the sub covering the Read More link to jump down to the next line (it's stuck to the bottom of the text), revealing the link.

I know there are people who believe that web development should be a math-free pursuit. I don't know why they believe that, but I've read their blogs and I know they're out there. This does require calculations (meaning those things you can do with a calculator). However, short of using the limited IE-only text-overflow property, any solution will require some math. Some people might think this makes CSS flawed and too difficult; I think it's one of its subtle beauties. Prior to PageMaker and InDesign, imagine any respectable publication laying out their newspaper or magazine without the use of a ruler. Never happened. Layouts with no math are HTML1 and we should be happy we're now able to use the left side of our brains.

I'd love to hear about any other problems with this solution, or any suggested improvements. In the meantime, here's the code:

<p class="trunc"><span>
<span id="dynamicText">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate
<img src="spacer_white.gif" /></span>
<sub>&nbsp;</sub>
<a href="#">See more »</a>
</span></p>
<style type="text/css">
p.trunc {
    position: relative;
    height:80px; /* line-height * desired number of lines */
    width:500px;
    overflow:hidden;
    line-height: 20px;
}
p.trunc span {
    position:relative;
    display: block;
    width:500px;
    z-index: 1;
    overflow:hidden;
}
p.trunc span#dynamicText {
	position: relative;
	display: inline;
	width: auto;
	z-index: auto;
	overflow: auto;
}
p.trunc span a {
    position:absolute;
    display: inline;
    top: 60px; /* line-height * (number of lines - 1) */
    left: 430px; /* container width - link width */
    width: 70px;  /* should be as tight as possible */
    background-color: #fff;
    z-index:2;
    text-align: center;
}
p.trunc span sub {
    position:absolute;
    bottom: 0;
	right: 0;
	width: 70px;  /* width of 'more' link */
    height: 20px; /* line-height */
    background-color: #fff;
    z-index:3;
}
p.trunc span img {
	width: 70px; /* width of 'more' link */
	height: 20px; /* line-height */
	vertical-align: top;
}
</style>
<!--[If lte IE 6]>
<style type="text/css" media="all">
p.trunc span sub {z-index:4;}
</style>
<![endif]-->
Update: There's a cool jQuery plugin that could easily be tweaked to do the same thing. I'm not sure it will work for multiple lines, but it does trim letters neatly instead of cutting them in half, which is the big issue I have personally with the method above..