Using CSS3 gradients to create text leading lines

The new CSS3 gradients are quite powerful and simple when in need of simple repeating background patterns. Although these will not work in older browsers and partly in newer browsers, they are an option to look for to lessen image usage for things that may work without the image file. This entry will guide you through to make leading lines for text (as has been for ages in notebook paper and similar stuff) using some CSS3. This effect can be useful for lines of code within <pre> tags and similar.

Many implementations use JavaScript to split out the wanted element to block-level line elements (using either paragraphs, divs or spans) for which then bottom (or top) borders are styled to create the text line effect. This is good for lines that need to wrap and “expand” the text line to denote what each single line holds in it. But some folks may have JavaScript disabled for various reasons, leaving the text lines unstyled. CSS3 offers a solution without JavaScript, but is less expandable. The best solution could be to mix both CSS3 and JavaScript.

This styling can be added to any HTML element that accepts background images (practically any block level element needed in layout code and text content). Here is the HTML we are using in this example:

<div class="example-element">
    <p>Some text before awesome text line styled content.>/p>
    <pre>
Some awesome text with even more awesome CSS3
styled background text lines. Let's try some code:

<?php
    $hello = "Hello world!";
    if ( $hello != "" )
    {
        echo $hello;
    }
?>
    </pre>
</div>

Nothing complex. Just a content holder div with some pre-content inside it. Here is the CSS for styling the text lines:

.example-element pre {
        /** We set the up and bottom padding to zero to avoid background movement. */
        padding: 0 5px;
        line-height: 20px;

        /** This will be used even if the browser doesn't know CSS3. */
        background-color: #EEE;

        /** The CSS3 background-image declarations: */
        background-image: background-image: -webkit-gradient( linear, 0 0, 0 100%,
            color-stop( .95, transparent ),
            color-stop( .99, rgba( 0, 0, 0, 0.5 ) ),
            to( rgba( 0, 0, 0, 0.5 ) ) );
        background-image: -o-linear-gradient( transparent 95%,
            rgba( 0, 0, 0, 0.5 ) 99%,
            rgba( 0, 0, 0, 0.5 ) );
        background-image: -moz-linear-gradient( transparent 95%,
            rgba( 0, 0, 0, 0.5 ) 99%,
            rgba( 0, 0, 0, 0.5 ) );
        background-image: linear-gradient( transparent 95%,
            rgba( 0, 0, 0, 0.5 ) 99%,
            rgba( 0, 0, 0, 0.5 ) );

        /** Background image sizing must be scaled to our line height to look correct: */
        -webkit-background-size: 20px 20px;
        -moz-background-size: 20px 20px;
        background-size: 20px 20px;
    }

Alright, a bit more complex than the HTML code we are using. Let me explain if something isn’t as clear as it should be from the code, mainly the gradient declarations.

First we set padding to zero for the top and bottom values, so we don’t get odd spacing for the background lines. You could change the background-position value to fix this too. Then we declare a proper line-height for the whole element. The same value is used in the background-size declaration later on.

The true work happens inside the background-image rules and the gradients. Each gradient is a whole 100% of size. We declare 95% of this as transparent. This way any element having backgrounds under the text line element will be shown too. You can use a solid color or a translucent shade here if you want. The rest 5% is filled with a solid color or a quite opaque color. I used a 50% shaded black (rgba( 0, 0, 0, 0.5 )). This way 95% of our background is transparent and the rest is a wanted color. Note: if your line-height exceeds about a hundred pixels in height, you should increase the percentage (95%) of the transparent area to avoid slight blurs in the background lines.

Without the background-size rule the single gradient would be stretched all over out pre element. By setting the background-size to the same value as our line-height is, we get a repeating pattern for all of our content lines.

Here is the result (remember, you need a CSS3 compliant browser to see it properly):

Some awesome text with even more awesome CSS3
styled background text lines. Let's try some code:

<?php
    $hello = "Hello world!";
    if ( $hello != "" )
    {
        echo $hello;
    }
?>

With some more complex implementations you can create varying colors for varying lines (every second line could be red for instance) and have vertical lines too (with multiple background image gradients). With JavaScript you can add some line numbering and other effects to your elements. I’m not a performance master (which is faster: this or a small image?), but this method leaves room for easily changing the line-height of the background lines with a few numbers, instead of loading up a complex image creating software (Photoshop or such) to create the image.

A big thanks to Lea Verou for the idea and inspiration to craft this one.

Update (25.05.2011): Lea Verou reminded me in the comments below to ensure compatibility with browsers that use text zooming (instead of full page zooming) to change the pixel values to ems or other relative units. Using pixels instead could break the line leading rhytm in text zooming browsers. Just something to keep in mind!

About Otto Rask

A young Finnish media engineer student. Besides school I dabble with web development, design, other digital stuff and computing. I like video games too.
This entry was posted in HTML/CSS and tagged , , , , . Bookmark the permalink.

2 Responses to Using CSS3 gradients to create text leading lines

  1. Lea Verou says:

    Maybe you should try using ems for the background-size, so that it doesn’t break when you change font-size. That’s what I did for my blog code snippets, although for some reason they still break in Webkit :(

  2. Otto Rask says:

    Lea Verou: Thanks for commenting!

    I didn’t want to bother myself too much with using ems for the background sizing declarations in this short tutorial. Of course it should be taken care of when using for a website project where it could do general harm to the visitor. This would require declaring the pre elements’ line heights to be relative units too. I’ll update my entry to remind other people to ensure they provide a version which does not break that easily.

    Using pixels does not break it when using full page zoom (not text zoom), which most new browsers are capable of (and as far as I know is the “default” nowadays).

    I’m not sure what could cause that Webkit problem, as I am not a “rendering expert” who would know about it. For me it’s more “try this and see what happens” when finding out what breaks and for what reason. ;)

    Thanks again for sharing this wonderful CSS3 technique on your site, has been quite fun playing around with it. :)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>