To begin, let me explain what I know exists and have tried variations of:
- The typical aspect ratio hack, which manages the height of an element based on a width.
- Stackoverflow answers, where the height is determined by an image, which then dictates the width of the container.
What I'm interested in is pure CSS solutions, with whatever hacky, new-fangled, experimental properties you can think of, that achieves the following results:
The height of the card is based on content (in this case a title and a paragraph). We'll call that h
. Another element within the card should be that same h
height (based on the content of a sibling), and whatever that h
amount is, it should also be the width of that element (to create a square).
Edit (2019-28-02): I apologize for not being clear on this next point but, in order to get the text to wrap, the area where the text sits should have a maximum width. Marc Bellêtre's solution is admittedly pretty close as of today.
This question is very similar to an older question which did not receive any responses. The difference is that the parent, in this case, is not receiving any explicit height values. The height of the parent card is purely determined by the text inside of it. I can imagine that if that question has not received any responses/solutions that this may fare no different, especially since this is slightly more difficult. However, new technologies have come around since then (ie.: flexbox/grid), that might be helpful.
Please, no JavaScript solutions. I'm very aware of how to achieve this using it.
Sometimes when I load this code, the box isn't even square. The big problem is it doesn't respect the height: 100%
at all but then it will be square after fiddling with resizing the browser or content. Updating the ratio makes the box grow unexpectedly large.
.card {
background: #ddd;
display: inline-flex;
}
.aspect-ratio {
border: 1px solid;
padding: 1em;
aspect-ratio: 1 / 1;
background: #ccc;
}
.content {
padding: 1em;
flex: 1 1 200px;
}
h3,
p {
margin: 0;
}
<div class="card">
<div class="aspect-ratio">(h)</div>
<div class="content">
<h3>Title</h3>
<p contenteditable>The more I type, the taller this box gets (h)</p>
</div>
</div>