Linebreaks via CSS Generated Content

10 June, 2013

Yes, folks – it’s time for another CSS hack. These are often an outcome of boredom, temporary lunacy or desperation, I confess. But there’s plenty to learn from them.

Imagine this use case
- You have a few links that you’re using to create a regular tab style interface, with a container that changes content based on which link you click.
- Each link has a bottom border on the selected link as well as on hover.

All’s well with the world. Until the last anchor (i.e. 'Hurricane') drops to the next line at some point on smaller screens.

You find it messy and decide to use a media query and drop the whole column below. Still going good, until you narrow the window down and see the anchors dropping to the next line, again. You convert the anchors to display block and those borders get converted into ugly lines spanning the width of the parent container. But you need those borders to span only the width of the text.


Note: The ideal way to do this would be to wrap each anchor in a div and then attend to those elements (via floats, inline-block or whatever) and apply the border to the link inside. On the appropriate media query, you would change the display property of the div back to block and ensure its width is 100%, and the anchor would maintain its inline border.
But this article’s about a CSS hack. It’s also about a situation where you may not be able to change the markup, and need a quick fix.

CSS Hack Solution

I had come across the solution on the very cool Lea Verou’s blog post last year (for a different use case) and didn’t think too much about it. Until I was faced with a problem and was looking for a way to force a linebreak for elements with inline displays.

The key here is to ensure that the anchors maintain their natural inline display (if you had changed it to inline-block, set it back to inline on the media query).

Use the content property to generate a line-break via a linefeed (the Unicode character U+000A), which you can escape like this:
content: “\A”

You will need to set the white-space to something with pre – I’m using white-space: pre-line.

Of course, setting the anchors back to display inline implies that the vertical margins and padding will not have an impact. I wanted vertical spacing between each anchor so users on small touch devices will easily be able to touch one at a time.

Solution? I increased the line-height and solved the problem.

Here is the demo.

Why does this not work for inline-block displays, by the way?
Lea Verou answered my question: “Because inline-block creates a separate box instead of multiple multiline boxes, so the line break is inside that box. Same behavior as appending a br”
Makes perfect sense :)

Demo here

Image source here

Related tags: CSS-Linebreaks, Generated-Content

comments powered by Disqus