Text reflections with css and javascript: jQuery text reflection plugin

If you want to create a reflected text header, an often used solution is to dynamically create an image for each header which includes the reflection. However, this has some disadvantages. Therefore, I have created a jQuery plugin which uses only javascript and css to create reflections, and all you have to do is drop it into your page to make it work.

You can see the plugin in action on the <h2>‘s on this very page.

Problems with image-based solutions

Using images for your headers has a few disadvantages:

  • It makes your page load slower (because every header requires its own http request)
  • If you want to define or change the look of the header, you have to change the configuration of the image generator
  • Generating the images server-side mingles the tasks of the frontend and backend developers
  • You’ll need some extra markup to make your headers accessible

So what I wanted to make was a plugin that does not require lots of http requests, allows you to style your headers using only css, and which does not require additional markup.

How to use the plugin

To use the plugin, just follow these simple steps:

  1. download the plugin and unzip it
  2. add jquery.textreflection.min.css to the head of your document
  3. put the images folder in the same folder as the css file
  4. add jQuery at the end of the body
  5. add jquery.textreflection.min.js at the end of the body (after jQuery)
  6. add class="textreflection" to every header (or any other text element) you want to have a reflection

(To allow easy inspection of the source code, I have used the uncompressed css and js files on this page.)

Finetuning the reflection

Depending on the css of your headers, the reflection may need some adjustments. You can finetune that in the css file. I’ve put the rules you may want to adjust at the beginning of the file.

How the plugin works

When the DOM is ready, the plugin searches every element which has a class of textreflection.
It then clones every element and flips it vertically. A div is then positioned on top of the clone, and as its background, it is given a css gradient which runs from 70% transparent to white. Browsers that don’t support css gradients get a gradient image as their background instead.

Possible improvements

Native reflections in Webkit

Webkit has a native css solution for reflections: -webkit-box-reflect. The plugin could be adjusted to use the native css for browsers that support it. (For more info on -webkit-box-reflect, read Mastering CSS Reflections in Webkit.)

Screen reader improvements

With my plugin, every header is being duplicated for the reflection. I’m not sure how screen readers will handle this, but I can imagine they’ll read every header twice. There may be a way to tell screen readers to ignore the cloned header, but I don’t know how. If you do, please let me know!

Je kunt niet (meer) reageren op deze post, maar nog wel een trackback toevoegen.

16 comments on “Text reflections with css and javascript: jQuery text reflection plugin”

  1. […] Text Reflection This plugin allows you to style your headers using only css and does not require additional markup. Browser Compatibility: Mozilla Firefox 1.5+, Google Chrome, Opera 9+, Safari and IE7+. […]

  2. Doesn’t work properly in Safari 5.0.3 on Windows XP Pro.

    zegt SafariProblem
  3. I am using Safari 5.1.2 on Windows XP Pro, and don’t see any issues there. What is going wrong?

    zegt jaron
  4. Viewing this blog entry on the iPhone 4S and the reflections are not rendered correctly in their text sizes?

    zegt Dielle
  5. @Dielle: Thanks for pointing that out! The problem occurs on my iPhone4 too. The odd thing is, that when I check the example page in the downloadable source, the reflection shows just fine. Maybe it’s got something to do with my column layout.

    I’m going to take a look at it as soon as I find the time, and will post an update when I have fixed the bug. I guess I’ll try implementing -webkit-box-reflect.

    As a quick fix, I have added a simple media query that hides the reflection on devices with a width up until 320px.

    zegt jaron
  6. Way cool!
    Thanks!

    I have an issue with centered text though where the reflection always ends up to the left… 😮
    What am I missing?

    Regards,
    Anders

    zegt Anders
  7. @Anders: Thanks for noticing! I have made a slight adjustment to the css that should solve your problem. Depending on how you have centered your text, you may also have to specify text-align: center; on the element with class textreflectionClone.

    For the sake of completeness: The heading with class textreflectionClone has a position: absolute;. Because of that, its containing block does not automatically take up the entire with of its parent element, like block elements normally do, but it wraps snugly around its content. That means there is no extra width to center the content in, so centering the text then doesn’t have any effect. By setting its width explicitly to 100%, I have now given the heading space to center its content in.

    zegt jaron
  8. Cool! Your rock! :)

    I really love this concept and it would be perfect, just awesome, if… there is always the “if”… :)
    If it could handle other background colors than white. I have a black background on my page and then grey in pop-up’s (Fancybox). Is it possible to get it working with different background-colors?

    Btw, you don’t have any “Donate” button…

    Regards,
    Anders

    zegt Anders
  9. @anders: you can also use this script with different background-colors. You’ll have to adjust two things: the gradient colors for the class textreflectionMask, and for browsers that do not support gradients, the gradient image (css/images/textreflection/gradient-white.png). A sample psd for that image is included in the zip-file.

    If you want to use different variants within one site, you’ll have to make seperate selectors and styles for each of the variants for the selectors .textreflectionMask and .noGradients.textreflectionMask.

    zegt jaron
  10. Any thoughts why IE compatability mode (and IE7) shows the reflection “non-inverted”?

    zegt Steve
  11. You’re missing the “gradient-white.png” -image from the package! So it doesn’t work with IE. Please include it in the plugin-package.

    zegt Jurvog
  12. @Jurvog: Thanks for noticing! I have updated the plugin-package.

    @Steve: The missing png-image Jurvog mentions may very well be the cause of your problem. Can you check it again with the updated package?

    zegt jaron
  13. I have a problem when the textreflection is generated by JavaScript:

    Here they are

    works fine, but, if I have

    and

    $(window).load(function()
    {
    document.getElementById(“div”).innerHTML = ‘Here they are’;
    });

    … does not. The test is there, but not the reflection.
    Any reason?

    zegt OlivierLD
  14. Sorry for the above, I need to escape the tags…
    I have a problem when the textreflection is generated by JavaScript:

    <h3 class=”textreflection”>Here they are</h3>

    works fine, but, if I have
    <div id=”div”></div>
    and

    $(window).load(function()
    {
    document.getElementById(“div”).innerHTML = ‘<h3 class=”textreflection”>Here they are</h3>’;
    });

    … does not. The test is there, but not the reflection.
    Any reason?

    zegt OlivierLD
  15. Hi OlivierLD, the reason that doesn’t work is that the plugin is being executed as soon as the dom is ready. You are filling your div after the plugin has executed.

    However, you can still call the plugin afterwards:

    $(window).load(function()
    {
    document.getElementById("div").innerHTML = '<h3 class="textreflection">Here they are</h3>';
    $('#div h3').textreflection();
    });

    and when you’re at it, I would call your code on dom ready, and alter it slightly:


    $(document).ready(function() {
    $('<h3>').html('myText').appendTo($('#div')).addClass('textreflection').textreflection();
    });

    zegt jaron
  16. Excellent! Many thanks for the tip!

    zegt OlivierLD