0

TL;DR
The square class should be a square in all testcases.

The following html includes three testcases. All testcases contain a flex-box which holds three divs. The div in the middle has a square class and (as the name suggests) should be a square in all testcases. The square should fill up as much space of the container as possible, but shouldn't exceed it of course.

I already found a solution here, but it fails on the second and third testcase.

The solution shouldn't include javascript if possible and shouldn't use aspect-ratio if possible, because it has bad browser support currently.

Any help is gratefully appreciated.

Codepen

.container {
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  background-color: red;
}

.simple {
  width: 100%;
  background-color: green;
}

.square {
  background-color: yellow;
}
<!-- 1. Testcase -->
<div class="container" style="width: 200px; height: 400px">
  <div class="simple">Hello</div>
  <div class="square">World</div>
  <div class="simple">Hello</div>
</div>

<!-- 2. Testcase -->
<div class="container" style="width: 400px; height: 200px">
  <div class="simple">Hello</div>
  <div class="square">World</div>
  <div class="simple">Hello</div>
</div>

<!-- 3. Testcase -->
<div class="container" style="width: 200px; height: 200px">
  <div class="simple">Hello</div>
  <div class="square">World</div>
  <div class="simple">Hello</div>
</div>
  • how can it be possible when your explicitly setting `height` and `width`!! – Kunal Tanwar May 25 '22 at 15:54
  • I specified the `width` and `height` of the testcase containers just for demonstrational purposes, but the `width` and `height` of the `square` div isn't explicitly set. – pastel-bucket May 25 '22 at 15:59

2 Answers2

1

Unless you need to support the deprecated IE you can use aspect-ratio:

.container {
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  background-color: red;
}

.simple {
  width: 100%;
  background-color: green;
}

.square {
  background-color: yellow;
  aspect-ratio: 1 / 1;
  width: 100%;
}
<!-- 1. Testcase -->
<div class="container" style="width: 200px; min-height: 400px">
  <div class="simple">Hello</div>
  <div class="square">World</div>
  <div class="simple">Hello</div>
</div>

<!-- 2. Testcase -->
<div class="container" style="width: 400px; min-height: 200px">
  <div class="simple">Hello</div>
  <div class="square">World</div>
  <div class="simple">Hello</div>
</div>

<!-- 3. Testcase -->
<div class="container" style="width: 200px; min-height: 200px">
  <div class="simple">Hello</div>
  <div class="square">World</div>
  <div class="simple">Hello</div>
</div>
tacoshy
  • 10,642
  • 5
  • 17
  • 34
  • thank you for taking the time and giving an answer. I forgot to mention in my initial request, that the `square` div should take up as much space as possible without exceeding the container. I edited my request to include this information. Just setting the `aspect-ratio` would keep the square small. – pastel-bucket May 25 '22 at 16:07
  • then just give the element a width of 100%; which will make them resize to fill the width. However you need to change then the `height` of the containign parent to `min-height`. Alternativly you can also use the fixed height in combination with `flex-grow` on the square. – tacoshy May 25 '22 at 16:13
1

To make you .square element to keep correct aspect ratio without aspect-ratio prop, you could use pseudo elements, see:

Also, if you don't want to use grid approach, you can make this container relative and it's child span element - absolute with correct positioning if needed.

.container {
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  background-color: red;
}

.simple {
  width: 100%;
  background-color: green;
}

.square {
  display: grid;
  grid-template-areas: 'content';
  background-color: yellow;
  width: 100%;
}

/* place text content and square pseudo el. to same cell */
.square:before,
.square > span {
  grid-area: content;
}

.square:before {
  content: '';
  display: block;
  width: 100%;
  padding-bottom: 100%; /* make it square */
}
<!-- 1. Testcase -->
<div class="container" style="width: 200px; min-height: 400px">
  <div class="simple">Hello</div>
  <div class="square"><span>World</span></div>
  <div class="simple">Hello</div>
</div>

<!-- 2. Testcase -->
<div class="container" style="width: 400px; min-height: 200px">
  <div class="simple">Hello</div>
  <div class="square"><span>World</span></div>
  <div class="simple">Hello</div>
</div>

<!-- 3. Testcase -->
<div class="container" style="width: 200px; min-height: 200px">
  <div class="simple">Hello</div>
  <div class="square"><span>World</span></div>
  <div class="simple">Hello</div>
</div>
Yaroslav Trach
  • 1,833
  • 2
  • 12
  • 18