Search code examples
htmlcssbackgroundpseudo-elementcss-content

Benefits/Drawbacks of using pseudo elements (:after, :before) vs. padding/background positioning?


I'm digging through some older code on a site that I'm working with, which uses iconize. The way that it seems to work is by adding a class like this...

a[href=$='.pdf']{
    padding: 5px 20px 5px 0;
    background: transparent url('icon.gif') no-repeat center right;
} 

Is there any benefit to doing it that way than the way that I'd have done it? Something like this...

a[href=$='.pdf']:after{
    content: url('icon.gif');
    vertical-align: sub;
}

Here's a fiddle to demonstrate both of them...

JSFiddle

My question is... What are the benefits, if any, of using pseudo-elements vs. standard padding and background positioning for appending/prepending images to elements?


Solution

  • Just a few initial and later thoughts. I may still think of some more to add.

    Padding/Background

    Advantage(s):

    1. Works for IE6-7 (i.e. older browsers).
    2. If one wanted to overlap the icon with the text, especially if centered, this would be easier to implement.

    Disadvantage(s):

    1. More thought needed to implement (must calculate some factors).
    2. For older browsers, only one background was supported, so if another background was needed, then there was a conflict to be resolved.
    3. If browser is set to not print background images, then a "gap" for the padding will still exist in the printed text, but no image will be there. This could be resolved through print media css.

    Pseudo-Elements

    Advantage(s):

    1. Easier to implement (no calculations needed).
    2. It can have its own padding, border, opacity, etc. applied if desired, just as if it were a real element.
    3. Related to #2, it can actually be moved outside the element if needed or desired.
    4. Semantically, it is being implemented in a more appropriate manner. The icon is not really a "background," but neither is it an essential part of the html that a content img might be, so the pseudo-element fits the bill for enhancing the presentation, but not causing issues if it is missing (in older browsers).
    5. In CSS3 browsers (and possibly CSS2), usually less code can be used to switch between right or left aligned icons (see "Discussion about code length" below).

    Disadvantage(s):

    1. Only one (of each type) allowed per element, so if it is needed for something else on an element, then you can have conflict.
    2. Not supported in older browsers.
    3. Some elements (replaced elements) cannot take pseudo-elements, so this would not even be an option.

    Discussion about code length

    EHLOVader noted in a comment to the question that part of his concern was extra coding that might be needed for pseudo-elements as opposed to background/padding if one wanted to switch to a left side icon. He gave this codepen example. However, it can be made to be less code to do a pseudo-element. Assuming .iconleft is a class used to put the icon left rather than right, and .iconit the class that sets an icon at all, then the following code concisely makes it happen for CSS3 browsers using the :not() selector (here is the fiddle, using the original .pseudo class of the OP for iconing):

    .iconit:not(.iconleft):after,
    .iconit.iconleft:before {
        content: url('http://www.jasonapollovoss.com/web/wp-content/uploads/2010/09/pdf_icon_small.png');
        vertical-align: sub;
    }
    

    The same could be done with CSS2 browsers if an iconright class is used to explicitly set an icon to the right, or iconleft to the left (no iconit class needed then):

    .iconright:after,
    .iconleft:before {
        content: url('http://www.jasonapollovoss.com/web/wp-content/uploads/2010/09/pdf_icon_small.png');
        vertical-align: sub;
    }