I’m trying to create the following CSS layout using flexbox:
Imagine the layout as a flex row, with one box on the left (the image) and to the right a flex column with all the text stacked on top of each other. The height of the box on the left automatically scaled to the height of the flex column to the right. I have gone up to this point so far, but I have been unable to get it into a square shape (as in the width is the same as the height).
Currently I have the code which produces the following result:
.container {
background: orange;
display: flex;
flex-direction: row;
}
.profile_pic {
aspect-ratio: 1/1;
background: blue;
}
.text_container {
display: flex;
flex-direction: column;
}
<div class="container">
<div class="profile_pic"></div>
<div class="text_container">
<h1>Name: Toby</h1>
<h2>Gender: Male</h2>
<h3>Password: 123</h2>
</div>
</div>
There is meant to be a square shaped blue box on the left of column which contains the text but it’s not showing for some reason?
If I set a specific width, it does show, but this is not what I want as I wish for the width to be the same as the height (maintain a 1/1 aspect ratio):
My current ‘workaround’ is wrapping the blue box in a flex with align-items
set to center
, and then making the blue box a hard coded size which roughly matches the height of the box:
I see lots of such similar layouts, for example the YouTube channel thing:
StackOverFlow indicator:
I believe such similar layouts are done by using workarounds such as setting an explicit height for the container or the image itself. This approach isn’t fine as there is always a small margin of error, and if I want to remove a line from the column flex to the right, I will need to manually adjust the sizes (it’s not dynamic).
Alas, I believe it’s quite an interesting issue and I hope that more knowledge can be collectively gained about how such layouts are done in CSS.
Any help would be greatly appreciated.
4
Answers
I don’t think this can be solved with CSS if you want to be as flexible as possible with regard to the height. But a few lines of JavaScript can do the job. First determine the
height
of the outer container. Then assign the received value aswidth
to the image container.It might be an advantage to assign an
ID
to each element instead of working with classes, but just with the provided code I can’t say that. However, you would then have to usedocument.getElementById()
instead ofdocument.querySelector()
.It should also be mentioned that
height
can be determined differently, depending on requirements:clientHeight – height + padding (currently in use)
offsetHeight – height + padding + border
And others, but that would be too much for now.
Here’s the snippet …
Try this out. In here you have to define a height value in the parent container.
It took me hours for this, I just thought it’s supposed to be simple but I couldn’t find the solution sooner. So after tweaking with flexbox, relative-absolute position, and even table layout, I just realized that we can use grid instead to achieve this. The most important thing in here is the
min-height: 100%
andheight: 0
on the first child. Theheight
must be zero so that it’s prevented from the grid height calculation, and themin-height
is so that it’s 100% of row’s height:You can change the image to something with a not 1/1 ratio, and you’ll see that it will stay in 1/1 ratio.
Also, as an option, you can set
.profile_pic { writing-mode: vertical-lr; }
..container
must havedisplay: grid;
: