Description
[EDIT] Use aspectRatio
style prop since RN 0.40+. Docs: aspectRatio
Starting this discussion thread around how to maintain aspect ratio of an image like it does in a browser. When we use <img src='example.com/image.jpg'>
in a browser, it renders a 0x0 block, then it fetches the image, looks at its width and height, then updates the layout with this new width/height bound by width/height set on container. So if the image is 400x300. It effectively gets a style of width: 400
and height: 300
. But if we configure styling to be width: 500
, then it fills in the other dimension height: 300
and is able to display the image.
Now in React Native, this behaviour does not exist for the right reasons. But we also lose this ability to somehow convey the size of the image. In React Native we are limited to giving width and height as part of the style
. But in scenarios where the width actually comes from the Flexbox behaviour - with something like alignSelf: stretch
, the height needs to be configured absolutely. So it ends up with the width taking the entire width from parent, but height being fixed. Using cover
on the image, we are able to fill this space with the image, but the image gets cropped.
@vjeux mentioned in #494 that he prototyped an implementation where you would pass in something like an aspectRatio
for the image, and then React Native would maintain that within the bounds of the configured styling - but he backed off because it is not part of the CSS standard. I have a suggestion on how we can do this (we use this method in our internal screen layout system that also uses css-layout).
In React Native, an image is configured like this: <Image source={{uri: "example.com/image.jpeg"}} />
, what we are missing here is information about the size of the image. What if we gave that info here in source
, and not as part of CSS style
info? So it would look something like this:
<Image source={{
uri: "example.com/image.jpeg",
height: 400,
width: 300
}} style={{
alignSelf: 'stretch'
}} />
In this example, the width of the Image would come from the parent, and it would pick the height based on the ratio inferred from the meta info in source
. The logic to this would remain the same as what @vjeux prototyped, but now we have a way to configure it outside CSS as there is nothing of this sort in the CSS spec itself. The source
spec is a React Native spec, and hence we can support two new properties width
and height
inside it to not have to fetch an image, but instead know the height and width of the image beforehand.