Can you apply a width to a :before/:after pseudo-element (content:url(image))?

derekmx271 picture derekmx271 · Feb 20, 2013 · Viewed 21.7k times · Source

This is in addition to my recent question: Is it possible to use pseudo-elements to make containing elements wrap around an absolutely-positioned element (like a clearfix)?

JSFiddle: http://jsfiddle.net/derekmx271/T7A7M/

I'm trying to use pseudo-elements to "clearfix" absolutely positioned images. I have gotten as far as getting the same image to display behind the slides, but cannot seem to apply widths to the inserted image. Am I crazy, or can you NOT apply widths to pseudo elements whose content is content: url(img/image.jpg)? I tried different variations of display:block, etc. to no avail...

#slider ul:after {
  content: url(http://www.cs7tutorials.com/img/slide1.jpg);
  display: block;
  position:relative;
  width:70px;
}

I need to set the width of the pseudo-element image to 100% and the max-width to 800px, so that it has the same dimensions as my slides.

Answer

BoltClock picture BoltClock · Feb 20, 2013

You're not crazy: it is indeed not possible to change the dimensions of an image that is inserted using content, whether it's inserted with url(), image(), image-set(), element(), or a CSS gradient. The image is always rendered as is. This is known as replaced content, or a replaced element (except we're not talking about elements here).

However, since replaced elements can be resized using width and height as described in section 10 of the CSS2.1 spec, this raises the question of why the properties don't seem to apply here. The answer to this, it would seem, is that the properties do apply, but to the pseudo-element box instead — you can see this by giving your pseudo-element a background color. Rather than replacing the pseudo-element box itself, the image is rendered as a child of the pseudo-element box, and therefore cannot be styled at all (as it would require another pseudo-element which doesn't exist).

And that lends itself to another question: why doesn't it replace the pseudo-element box altogether? Unfortunately, CSS2.1 does not specify this behavior at all, so the implementation that was agreed on is to render the content as a child of the pseudo-element box instead:

CSS2.1 doesn't really clearly define the processing model of 'content' on ::before and ::after, but the informative examples in CSS 2.1, the fact that 'content' specifies a list of things, and the desire for consistency has led to UA behavior being the following: the 'content' property specifies a list of things that become children of the ::before or ::after box.

-Boris

Hopefully this will be further addressed in CSS Generated Content level 3, on which rewriting work has just begun.

In the meantime, if you want to be able to resize the :after pseudo-element and the image that's generated, you will need to apply it as a background image instead and — assuming browser support isn't an issue — use background-size along with width and height to scale it (based on the understanding that those properties apply to the pseudo-element box instead).