ChatGPT解决这个技术问题 Extra ChatGPT

Can I change the height of an image in CSS :before/:after pseudo-elements?

Suppose I want to decorate links to certain file types using an image. I could declare my links as

<a href='foo.pdf' class='pdflink'>A File!</a>

then have CSS like

.pdflink:after { content: url('/images/pdf.png') }

Now, this works great, except if pdf.png isn't the right size for my link text.

I'd like to be able to tell the browser to scale the :after image, but I can't for the life of me find the right syntax. Or is this like background images, where resizing just isn't possible?

ETA: I'm leaning towards either a) resizing the source image to be the "right" size, server-side and/or b) changing the markup to simply supply an IMG tag inline. I was trying to avoid both those things but they sound like they'll be more compatible than trying to do stuff purely with CSS. The answer to my original question seems to be "you can sort of do it, sometimes".

Is there a compelling reason that you're not using 'img' tags with 'a' tags wrapped around them? That's the more typical syntax for an image that is also a link. I say this because even if you get your method to work, you may be confusing other developers. CSS also has a strong reputation for inconstancy between browsers/versions.
I appreciate the issue, it's just that I don't necessarily control the markup generation -- in this case I can only re-style, not re-structure.
Lengthy discussion on the W3C mailing list: lists.w3.org/Archives/Public/www-style/2011Nov/…

A
Ansel Santosa

Adjusting the background-size is permitted. You still need to specify width and height of the block, however.

.pdflink:after {
    background-image: url('/images/pdf.png');
    background-size: 10px 20px;
    display: inline-block;
    width: 10px; 
    height: 20px;
    content:"";
}

See the full Compatibility Table at the MDN.


This is great except that most of our clients are on IE 7 or 8 (corporate nonsense, sorry).
If that's the case, you shouldn't be using :after at all. It's not supported below IE8.
This technique also required setting width: 10px; height: 20px; to see the image.
To note also that this indeed works, but only with the specific background-image property, the simple background will not work.
(For :before) I also needed position: absolute, and left: -10px.
C
Community

Note that the :after pseudo-element is a box, which in turn contains the generated image. There is no way to style the image, but you can style the box.

The following is just an idea, and the solution above is more practical.

.pdflink:after {
    content: url('/images/pdf.png');
    transform: scale(.5);
}

http://jsfiddle.net/Nwupm/

Drawbacks: you need to know the intrinsic dimensions of the image, and it leaves you with some whitespace, which I can't get rid of ATM.


zoom: 0.5 is also worth considering.
I like the idea of this solution, but it throws the positioning off, esp in an inline-block scenario. (IE 11)
zoom is not well supported.
the jsfiddle is not changing the size. I'm using the latest Firefox. I also tried the last jsfiddle example in this post using zoom, and it does not work, either.
Just a note: in my case, I had to put position: absolute in order to get transform: scale(0.5) to actually work. I also had to put position: relative in the "parent" element (the owner of the :after pseudo) for sanity. Also, I had to add translate(-16px, -16px) to my transform to position the 16x16 icon correctly. The position: absolute also has the benefit of eliminating the whitespace problem.
u
user123444555621

Since my other answer was obviously not well understood, here's a second attempt:

There's two approaches to answer the question.

Practical (just show me the goddamn picture!)

Forget about the :after pseudo-selector, and go for something like

.pdflink {
    min-height: 20px;
    padding-right: 10px;
    background-position: right bottom;
    background-size: 10px 20px;
    background-repeat: no-repeat;
}

Theoretical

The question is: Can you style generated content? The answer is: No, you can't. There's been a lengthy discussion on the W3C mailing list on this issue, but no solution so far.

Generated content is rendered into a generated box, and you can style that box, but not the content as such. Different browsers show very different behaviour

#foo {content: url("bar.jpg"); width: 42px; height:42px;} #foo::before {content: url("bar.jpg"); width: 42px; height:42px;} Chrome resizes the first one, but uses the intrinsic dimensions of the image for the second firefox and ie don't support the first, and use intrinsic dimensions for the second opera uses intrinsic dimensions for both cases

(from http://lists.w3.org/Archives/Public/www-style/2011Nov/0451.html )

Similarly, browsers show very different results on things like http://jsfiddle.net/Nwupm/1/ , where more than one element is generated. Keep in mind that CSS3 is still in early development stage, and this issue has yet to be solved.


@TJ Each separate answer deserves an answer (If that's not obvious enough), which will get different amounts of upvotes and will be seen/quoted/shared differently based on the contents of the answer.
s
santillanix

You should use background instead of image.

.pdflink:after {
  content: "";
  background-image:url(your-image-url.png);
  background-size: 100% 100%;
  display: inline-block;

  /*size of your image*/
  height: 25px;
  width:25px;

  /*if you want to change the position you can use margins or:*/
  position:relative;
  top:5px;

}

D
Dmytro Yurchenko

diplay: block; have no any effect

positionin also works very strange accodringly to frontend foundamentals, so be careful

body:before{ 
    content:url(https://i.imgur.com/LJvMTyw.png);
    transform: scale(.3);
    position: fixed;
    left: 50%;
    top: -6%;
    background: white;
}

D
Dharman

Yes, the original question was asked eight years ago, but it's actually relevant today as its always been. Now, I've been going from pillar to post over this issue of ::before, for about a week ::after, and its been driving me round the bend.

From this page, and others on the subject - I've finally put it together and sized an image down in the pseudo tag.

** Running note .colnav is just my container class, that holds an < UL > and < LI > set of tags with a set of < a hrefs inside.

Below is the code (complete)

.colnav li.nexus-button a:hover:before { background-image: url('/images/fleur-de-lis.png'); background-size: 90px 20px; background-repeat: no-repeat; width: 130px; height: 20px; margin-left: -120px; margin-top: -3px; transform: scale(1.5); content: ""; position: absolute; }

The image file was (is) 120 x 80, and the picture got reduced right down to 90x 20, where it then fitted quite nicely behind the html href tag, and it all came together with that position: absolute statement at the end.


T
Thomas

Here is another (working) solution : just resize your images to the size you want :)

.pdflink:after {
    display: block;
    width: 20px;
    height: 10px;
    content:url('/images/pdf.png');
}

you need pdf.png to be 20px * 10px for this to work. The 20px/10px in the css are here to give the size of the block so that the elements that come after the block are not all messed up with the image

Don't forget to keep a copy of the raw image in its original size


It's call jokes !!
R
Ravi Soni
.pdflink:after {
    background-image: url('/images/pdf.png');
    background-size: 10px 20px;
    width: 10px; 
    height: 20px;
    padding-left: 10px;// equal to width of image.
    margin-left:5px;// to add some space for better look
    content:"";
}

U
Usman Ahmed

Instead of setting the width and height of the background image, you can set width and the height of the element itself.

.pdflink::after {
  content: '';
  background-image: url(/images/pdf.png);
  width: 100px;
  height: 100px;
  background-size: contain;
}

P
Plamen

You can use the zoom property. Check this jsfiddle


Checking the jsfiddle, both are the same size and zoom is highlighted in red.
It does not resize in Firefox 53 at the moment. Hopefully, this can be implemented in a later version of Firefox. It's good to know that it works in Chrome at least. :-)
r
rhysclay

Nowadays with flexbox you can greatly simplify your code and only adjust 1 parameter as needed:

.pdflink:after {
    content: url('/images/pdf.png');
    display: inline-flex;
    width: 10px;
}

Now you can just adjust the width of the element and the height will automatically adjust, increase/decrease the width until the height of the element is at the number you need.


Didn't work for me, maybe because the image is svg, maybe because the parent is a flex container.
not on a jpg either url(//placeimg.com/800/200/arch)
I found this answer worked for me with the addition of: content-visibility: hidden; (can't explain why that worked as such.
N
Nesha Zoric

You can change the height or width of the Before or After element like this:

.element:after {
  display: block;
  content: url('your-image.png');
  height: 50px; //add any value you need for height or width
  width: 50px;
}

A
Andre Jesus Seiji Nishi

I used this font size control width

.home_footer1::after {
color: transparent;
background-image: url('images/icon-mail.png');      
background-size: 100%;      
content: ".......................................";
font-size: 30pt;
}

u
uyghurbeg
content: "";
background-image: url("yourimage.jpg");
background-size: 30px, 30px;