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

22,142

Solution 1

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).

Solution 2

You can set either width or height, but not both, by using display: flex and setting flex-direction to the opposite axis of the dimension you wish to set.

For example:

.setWidth::before {
    content: url("myImg.png")
    display: flex;
    flex-direction: column;
    width: 200px;
}

.setHeight::before {
    content: url("myImg.png")
    display: flex;
    flex-direction: row;
    height: 200px;
}

Demonstration here.

Share:
22,142
Derek Foulk
Author by

Derek Foulk

Updated on May 12, 2021

Comments

  • Derek Foulk
    Derek Foulk almost 3 years

    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.

  • otinanai
    otinanai about 11 years
    However, it seems that you need to have a specific height for your pseudo element.
  • Derek Foulk
    Derek Foulk about 11 years
    It definitely shrunk the image display, however it lost the ability to push the elements down... I think I'm just reaching for the stars here for a solution to the absolute positioned dilemma.
  • otinanai
    otinanai about 11 years
    If you set a height for the pseudo element it will push the other element down.
  • user3790069
    user3790069 about 9 years
    Don't you know, by chance, if this restriction is documented anywhere? I couldn't find it here
  • BoltClock
    BoltClock about 9 years
    @user3790069: No, I couldn't find it either. That's the problem. I have a possible explanation, but I think I'm going to propose it to www-style and see if I'm right and if so, I'll update my answer.
  • krulik
    krulik almost 8 years
    Best answer on the subject!
  • Jeow Li Huan
    Jeow Li Huan almost 2 years
    Works in Firefox but not in Chrome