I have a layout where an image has height: 100%, which is known (equal to 2.5cm in the following example), and the image width is supposed to propagate to the outermost block. However, the width that the image propagates is wrong; it seems to be equal to the width the image would have if it occupied the full grid height, rather than just the height of its row.
#block(
fill: gray,
height: 5cm,
width: auto,
grid(
// Changing this from 1fr to 2.5cm fixes it.
rows: 1fr,
block(
fill: red,
// Setting height: 2.5cm inside the image also fixes it.
image("logo.svg"),
),
rect(height: 100%, width: 1cm, fill: green),
),
)
Doing any of the edits mentioned in the comments produces this expected result where the outermost block (gray) has width of the widest contained element (image):
Rendered image
Adding more rows doesn’t affect the issue, i.e.:
My question is whether I am doing something wrong, and if it’s possible to get the correct outermost block width without resorting to hardcoding the height of a single row, either in rows: or in images’ height:.
Before we move on, I want to give some constructive criticism so that you can improve your later questions and help others understand your problem better. :)
Providing a MWE/MRE (Minimal Working/Reproducible Example) is essential (for questions based on user-written Typst code). This means that things like width: auto should be excluded from example as block.width is equal to auto by default. This visually adds unnecessary noise to an already non-trivial example. I was also confused as to why you say “I have a layout where an image has height: 100%” but then in the example below the image does not have the height field set. And below there is supposedly an output of the code above. Here, I created a version of MRE based on your first code block:
Which means that your code and its output does not match. However, adding the height: 100% to the image() that you were talking about does give the result from the first screenshot:
Lastly, trying to substitute a real image with a block() (if a source image wasn’t provided) is sometimes possible, but not in this case. This is because image() has different fields and default behavior. So attaching an image (source file) that is used in the MRE will also be a huge plus. Like this: https://forum.typst.app/uploads/short-url/grd9UaagVM15hPivZXyf7xWbTSA.png or this:
2.5x4.9cm.png
Now let’s get back to the problem at hand.
I made a small addition so that anyone can debug the example better:
#block(fill: gray, height: 5cm, grid(
fill: purple, // same area as gray
rows: 1fr,
grid.cell(fill: orange, block(
fill: red,
image("2.5x4.9cm.png", height: 100%),
)),
rect(height: 100%, width: 1cm, fill: green),
))
After playing around with this it kinda seems like this is a bug, or I just can’t keep all the constraints in my head. To be completely fair, there are quite a lot of constraints/value to keep track of.
My first question will be: do you have to add height: 100% to the image()? If you keep it at auto (by default), then it looks like what you want it to be (see the very first example of mine). You can set the height of the block() that immediately wraps around the image() instead, which won’t change anything visually in this situation.
If your question is only about 1 of the code snippets that you’ve attached, then let’s focus only on 1 of them. I think juggling 2 of them adds more unnecessary work. ;)
Sorry, I put it there thinking it would make it clearer that I want auto sizing for the outermost container (which happens to be box in this example).
Huh, for me the code produces the unexpected layout as is. I guess it could be because the image I was using has a natural size “big enough” so that it gets the equivalent of height: 100% in this example?
Here’s the image that I’m using: logo.png (can’t upload the .svg, but I checked and this .png that I exported works the same)
Well, I’m not sure, but you can check the natural size in some graphics editor or via exiftool:
exiftool 2.5x4.9cm.png | grep -e Pixel -e Image
# Image Width : 579
# Image Height : 295
# Pixels Per Unit X : 11811
# Pixels Per Unit Y : 11811
# Pixel Units : meters
# Image Size : 579x295
python3 -c 'print(295/11811 * 100)'
# 2.497671662009991
python3 -c 'print(579/11811 * 100)'
# 4.902209804419609
FYI, you’ve uploaded a JPEG, not PNG. I don’t know if this is due to conversion or something, but the natural size of it is 15.9 by 8.16 cm, which is not even close to 2.5 cm. But now I indeed have the same output as yours without modifying the image height. I checked and there is no difference with a version I have from 2024-09-09T00:00:00Z. So this is not something that was “fixed” at some point.
Hmm, for this example, this does look more like a bug than anything.
If someone creates an issue, please share the link here, so we can easily find it.
Interesting. I wonder if this is because of the Trust Level. I need to ask moderators about that. When I created a PNG image, it looks like it uploaded it verbatim with exception for the file name.
Thanks for creating the issue and linking it and this topic together.