Forum Bugs

img:before breaks max-width

Johann
I received the request to replicate the Word function 'Line Numbers' for our generated documents.
That can be done with the help of sidenotes, at least for elements like paragraphs, table rows and images.

But I encountered the following problem: The selector "img:before" breaks the "max-width" property of the image!

Example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Image with Caption</title>
    <style>
        img:before {
            content: "This is a 10cm Circle";
            display: block;
        }
        img { display:block; max-width:5cm; }
    </style>
  </head>
  <body>
    <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTBjbSIgaGVpZ2h0PSIxMGNtIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI1MCIgZmlsbD0iYmx1ZSIgLz4KPC9zdmc+Cg==" alt="10cm Circle"/>
  </body>
</html>


The setting "max-width: 5cm" for img is ignored in this case.

- - -
Johann

howcome
The SVG image you include explicitly says it's 10cm wide:

<svg width="10cm" height="10cm" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <circle cx="50" cy="50" r="50" fill="blue" />
</svg>


So, it will overflow its allotted width, which is 5cm (as per you setting on 'max-width'). You can hide the overflow by setting:

img { display:block; max-width:5cm; overflow: hidden }


So, 'max-width' is not ignored, but it has no saying on the overflow.
  1. foo.html0.6 kB
  2. foo.pdf18.1 kB

Edited by howcome

Johann
Then please explain why the image is scaled to 5cm when I remove the "img:before" rule :-)

- - -
Johann

howcome
Hmm. I don't understand why the SVG is presented differently with/without the generated element.
Johann
You invented CSS, who else should understand it?

- - -
Johann

howcome
Don't use that against me :--)

I think this is a Prince issue.

Hmm.
markbrown
> You invented CSS, who else should understand it?

@howcome has created a monster :-D

The :before selector creates a pseudo-element that is the first child of the matched element, but I don't know what this is supposed to do in the case that the matched element is a "replaced" element like an img. Chrome and Firefox don't seem to allow it.

I think Prince would be adding an anonymous block to contain the pseudo-element and the image, and the max-width property would end up here rather than on the image directly. That would explain the difference in behaviour.

Do any browsers produce the effect you are after?

Mark

Edited by markbrown

Johann
No, browsers do not support ':before' on <img> elements because it usually doesn't make sense in this context.

But your software can do more than a browser can!

To illustrate our use case, I have posted 2 attachments.
As mentioned above, we use sidenotes to generate (kind of) line numbers. In the first case, the SVG image is embedded in a <div> element and the <div> receives a ":before". But sometimes the image appears in the running text and ':before' is applied directly to the <svg>. In the latter case the image scaling problem occurs.


- - -
Johann

  1. DIV_withSidenote.png79.3 kB
    Image wrapped in a DIV with sidenote
  2. IMG_withSidenote.png50.2 kB
    Image with sidenote
markbrown
The issue is that you're expecting ':before' to create a sibling that precedes the matched element, but that's not what it does. It creates a child that precedes the existing content of the matched element, and as such would be included in the 'max-width' calculation. That's not what you're intending, though.

If ':before' is on the parent then 'max-width' does as you expect, which is why the first case works.

> But your software can do more than a browser can!

Alas, in this case I suspect it is a bug not a feature, since replaced elements like images shouldn't really be showing children in the first place.