简体   繁体   中英

Set a div's height to be equal to calculated width

This is my code (explanation after): https://jsfiddle.net/L7a35dda/1/

 body { width: 1920px; height: 1080px; background-color: rgb(48, 48, 48); margin: 0; padding: 0; display: flex; flex-direction: column; flex-wrap: wrap; align-items: flex-start; align-content: flex-start; } /* Overall Styles */ .group-container { display: flex; flex-direction: column; } .group-header { height: 40px; background-color: rgb(21, 101, 192); } .group-body { flex-grow: 1; display: flex; } .tile { display: flex; flex-direction: column; } .tile-header { background-color: rgb(25, 118, 210); } .tile-body { flex-grow: 1; } /* Group 1 */ #group-1 { width: 50%; order: 1; border-right: 3px solid black; border-bottom: 3px solid black; } #group-1 .group-body { flex-wrap: wrap; align-items: flex-start; align-content: flex-start; } #group-1 .tile { width: calc(100% / 3); height: 300px; /* Placeholder: Actual value needs to be equal to width */ } /* Group 2 */ #group-2 { width: 50%; order: 2; flex-grow: 1; border-right: 3px solid black; border-top: 3px solid black; } #group-2 .group-body { flex-direction: column; align-items: flex-start; } #group-2 .tile { flex-grow: 1; width: 100%; height: 100%; } /* Group 3 */ #group-3 { width: 50%; height: 100%; order: 3; border-left: 3px solid black; } #group-3 .group-body { flex-direction: column; } #group-3 .tile { flex-grow: 1; width: 100%; height: 100%; } 
 <div id="group-1" class="group-container"> <div class="group-header">Group 1</div> <div class="group-body"> <div class="tile"> <div class="tile-header">Tile 1A</div> <iframe class="tile-body"></iframe> </div> <div class="tile"> <div class="tile-header">Tile 1B</div> <iframe class="tile-body"></iframe> </div> <div class="tile"> <div class="tile-header">Tile 1C</div> <iframe class="tile-body"></iframe> </div> <div class="tile"> <div class="tile-header">Tile 1D</div> <iframe class="tile-body"></iframe> </div> <div class="tile"> <div class="tile-header">Tile 1E</div> <iframe class="tile-body"></iframe> </div> <div class="tile"> <div class="tile-header">Tile 1F</div> <iframe class="tile-body"></iframe> </div> </div> </div> <div id="group-2" class="group-container"> <div class="group-header">Group 2</div> <div class="group-body"> <div class="tile"> <div class="tile-header">Tile 2A</div> <iframe class="tile-body"></iframe> </div> <div class="tile"> <div class="tile-header">Tile 2B</div> <iframe class="tile-body"></iframe> </div> </div> </div> <div id="group-3" class="group-container"> <div class="group-header">Group 3</div> <div class="group-body"> <div class="tile"> <div class="tile-header">Tile 3A</div> <iframe class="tile-body"></iframe> </div> </div> </div> 

The above code aims to divide the screen into three groups of tiles:

  • Group 3 takes up the entire right side of the screen - its width is configurable (presently set to 50%). Its contents can be disregarded as it is presently a placeholder for future development.
  • Group 1 takes up the upper section of what remains of the left side of the screen, containing 6 square-shaped tiles in a 3x2 layout. The width of each tile should be equal.
  • Group 2 fills up the last remaining space beneath Group 1. It has 2 tiles in a vertical layout, spanning across the entire available width and height, distributing the vertical space evenly between them.

So the code seems to do everything I need it to do, except for the part where I need the Group 1 tiles to be square-shaped. I am currently hard-coding it as a placeholder for this question - that cannot be done in the actual product because it will be deployed onto multiple machines across a network, rendering onto different media of varying screen resolutions.

How should I change my code to achieve this?

Edit : Changed question title from iframe to div because the question was originally targeted towards that, though the final posted question is directed towards the tile div instead.

Credits to ovokuro for linking me the question containing the answer that suits my purpose but since the solution is in that question's comments, I'll re-post it here as a proper answer: http://jsfiddle.net/B8FU8/6245/

 .outer { display: flex; flex-wrap: wrap; flex-direction: row; } #container { position: relative; flex-basis: 20%; outline: 1px solid #eee; text-align: center; } #dummy { margin-top: 100%; } #element { position: absolute; top: 0; bottom: 0; left: 0; right: 0; background-color: silver; } 
 <div class="outer"> <div id="container"> <div id="dummy"></div> <div id="element"> some text </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text2 </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text3 </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text4 </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text5 </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text6 </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text7 </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text8 </div> </div> <div id="container"> <div id="dummy"></div> <div id="element"> some text9 </div> </div> </div> 

After fiddling around with the jsfiddle answer I found, I discovered that the display properties in #container are redundant to the solution, so I've removed them from my code snippet.

The particular components making up this solution are:

  1. #container - position: relative and, of course, a width value
  2. #element - all the properties specified except background-color .
  3. #dummy - margin-top

According to the explanations provided in the answer linked above, point 3 sets the aspect ratio: When margins are specified as a percentage value, it is computed as a percentage of the containing element's width. So if the value is 100%, it stretches the containing element to an aspect ratio of 1:1. A value of 75% will stretch it to 4:3, and so on so forth.

After setting the aspect ratio, points 1 and 2 work collectively to ensure the actual content of the container will fill the entire space.

Credits to JesseBuesking for the jsfiddle answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM