Truncation with CSS (Sassy)

Using SASS and a few basic properties in CSS, we can acheive an effect to dynamically truncate lists of content and present a count of how much content is being hidden to the user.

Subject Matter
Development

Author

Published
September 27, 2013

Share
Facebook Tweet

Depending on design, elegantly truncating content can be difficult. Properties have popped up in CSS like text-overflow, allowing for horizontal truncation of text using ellipsis and author-defined strings like "[more]". Using level 3 selectors in CSS, we can also target children after a specified number using something like li:nth-child(n + 5) (5 acting as an offset, here). With that, we can imagine that anything is possible, and it is—kinda maybe not.

I was presented with a design concept recently that included a string of text saying how many other pieces of content were hidden after fitting the content into the design. At the time it made sense in a CMS to truncate on the server side in the array, though anticipating other layouts, it could be useful to present more (or less) content depending on the available screen space.

We could go the route of a javascript implementation, but wondering if CSS’s abilities are at that level, I ventured off the beaten path a bit to see if we could make something using only CSS. It’s possible, too, that a CSS implementation would allow for content to still be accessible to screen readers & other machines for indexing.

Spoiler Alert: it went ok I guess.

To make the explanation a little easier, I whipped up a codepen with a relevant example.

CSS has a couple properties that we’ll use; counter-resetcounter-increment, and CSS’s content. The idea is that we have 8 child items, and we only want to display 5, alongside a count of how many children are excluded. Using counter-reset, we can start a counter at :nth-child(5), which will count all siblings starting at the fifth. If we use the counter on all the following children and follow that to the last child (think :last-child), we get the number of children omitted, outputtable as CSS content.

li:last-child{
  content: "&" counter(child-counter) " others";
}

So the information is there, but there are some janky stylez to handle from here. Because we’re using a pseudo element, it’s technically inside the last element, so dependent on your layout preference (i’m usin’ floats), the styling used to drop the fifth child onward should be overridden for the last child, and the pseudo element can be positioned relative to its parent.

The real fun comes in with media queries (or ends there if you’re not into that kind of thing). We have to rewrite some styles, but if we’re using SASS we can make a super clean, programatic way to handle breakpoints and retruncate… re… retruncate? our list of elements.

By setting our limits as variables, and our styles as mixins, we can call them in our media queries, and the only thing we have to redeclare in our media queries is the selectors, and the @includes can stay the same.

@media screen and (min-width: $break-med) and (max-width: $break-big){
  li:nth-child(#{$limit-big+1}){
    counter-reset: $counter;
  }
  li:nth-child(n + #{$limit-big+1}){
    @include item-hidden;
  }
  li:last-child{
    @include item-last
  }
}

This is a rough thing to implement, given that our pseudo-element requires some extra care in styling, but the fact that we can even have this ability in CSS is fantástico, so please fork that codepen and share some other use cases!