Skip to content

Instantly share code, notes, and snippets.

@aayla-secura
Last active June 9, 2024 12:42
Show Gist options
  • Save aayla-secura/e8c4dc0e4532be70c488f3ddf5c409a1 to your computer and use it in GitHub Desktop.
Save aayla-secura/e8c4dc0e4532be70c488f3ddf5c409a1 to your computer and use it in GitHub Desktop.
Automatically calculate flex basis of text and image for equal height
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title></title>
<script src="helpers.js" charset="utf-8"></script>
<script src="flex-auto-size.js" charset="utf-8"></script>
<style type="text/css" media="screen">
/* XXX */
:root {
--flex-auto-size-max-width-r: 1.7;
--flex-auto-size-max-free-r: 0.4;
}
* {
box-sizing: border-box;
}
.flex-auto-size {
--flex-auto-size-txt-width: 70%;
--flex-auto-size-img-width: 30%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
border: solid 1px black;
max-width: 800px;
}
.flex-auto-size.wide {
max-width: 1200px;
}
.flex-auto-size.narrow {
max-width: 400px;
}
.flex-auto-size-text {
flex-basis: var(--flex-auto-size-txt-width);
border: solid 2px red;
}
.flex-auto-size-text.large {
font-size: 24px;
}
.flex-auto-size-img {
flex-basis: var(--flex-auto-size-img-width);
border: solid 2px darkgreen;
}
.flex-auto-size-img img {
width: 100%;
height: auto;
background-color: grey;
border: solid 2px blue;
}
.flex-auto-size-img.cropV img {
margin: -20% 0;
}
.flex-auto-size-img.cropH img {
margin: 0 -20%;
}
button {
margin: 10px 0;
}
</style>
</head>
<body>
<!--
----------------------------------------------------------
---------------------- DEFAULT TEXT ----------------------
----------------------------------------------------------
-->
<!--
----------------------------------------------------------
--------------------- DEFAULT FLEXBOX --------------------
----------------------------------------------------------
-->
<!-- ------------------------- SQUARE ------------------------- -->
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<!-- ------------------------- WIDE ------------------------- -->
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<!-- ------------------------- TALL ------------------------- -->
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<!--
----------------------------------------------------------
--------------------- NARROW FLEXBOX ---------------------
----------------------------------------------------------
-->
<!-- ------------------------- SQUARE ------------------------- -->
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<!-- ------------------------- WIDE ------------------------- -->
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<!-- ------------------------- TALL ------------------------- -->
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<!--
----------------------------------------------------------
---------------------- WIDE FLEXBOX ----------------------
----------------------------------------------------------
-->
<!-- ------------------------- SQUARE ------------------------- -->
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<!-- ------------------------- WIDE ------------------------- -->
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<!-- ------------------------- TALL ------------------------- -->
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<!--
----------------------------------------------------------
----------------------- LARGE TEXT -----------------------
----------------------------------------------------------
-->
<!--
----------------------------------------------------------
--------------------- DEFAULT FLEXBOX --------------------
----------------------------------------------------------
-->
<!-- ------------------------- SQUARE ------------------------- -->
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<!-- ------------------------- WIDE ------------------------- -->
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<!-- ------------------------- TALL ------------------------- -->
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<!--
----------------------------------------------------------
--------------------- NARROW FLEXBOX ---------------------
----------------------------------------------------------
-->
<!-- ------------------------- SQUARE ------------------------- -->
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<!-- ------------------------- WIDE ------------------------- -->
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<!-- ------------------------- TALL ------------------------- -->
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size narrow">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<!--
----------------------------------------------------------
---------------------- WIDE FLEXBOX ----------------------
----------------------------------------------------------
-->
<!-- ------------------------- SQUARE ------------------------- -->
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@1.5x.png">
</div>
</div>
<!-- ------------------------- WIDE ------------------------- -->
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Mature_flower_diagram.svg/1040px-Mature_flower_diagram.svg.png">
</div>
</div>
<!-- ------------------------- TALL ------------------------- -->
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
<div class="flex-auto-size wide">
<div class="flex-auto-size-text large">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div><button>FOO</button></div>
<div><button>FOO</button></div>
</div>
<div class="flex-auto-size-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Lillium_Stamens.jpg/600px-Lillium_Stamens.jpg">
</div>
</div>
</body>
</html>
/*
* TODO:
* - flex-shrink calculation
* - prevent unnecessary reflows; e.g. avoid getting the computed styles
* - better handling of margins on elements: determine if absolute or relative
* to element size or viewport
* - get size of text nodes inside text container, i.e. text that's not inside
* an element on its own
* - which height to choose in case of free space? Should we choose a height
* in that range based on the image aspect ratio, i.e. choose smallest
* height for tall images, largest height for wide images and something in
* the middle * for roughly square ones?
*
* A text box has a fixed area, its height decreasing as width increases.
* Whereas an image has a fixed aspect ratio, its height increasing as width
* increases.
*
* We want to find an optimal configuration at which the text container (which
* can include other elements apart from the text box) and image heights are
* equal, or if not possible, at which they are as close as possible to each
* other while satisfying as best as possible these "guidelines" (constraints
* that are not enforced), based on visual appeal:
* - maxWidthR, maximum ratio between the width of the wider child and the
* narrower child
* - maxFreeR, maximum free space in the container as a percentage of its
* total width
*
* Then:
* 1. We set the flex-basis as the optimal width
* 2. Leave flex-grow as 0 (default).
* 3. The flex-shrink value would depend on how the font-size scales with
* viewport width as well as the current flexbox width and if there is free
* space or not. It's not straightforward
*
* ~~~~~~ FORMULAE: text and image width as a function of their height ~~~~~~
*
* For a given height, h, the widths of the text and image are:
*
* txtArea
* txtW(h) = —————————————
* h - txtExtraH
*
* imgW(h) = imgAspectR * h
*
* where txtExtraH comes from buttons and other non-text elements inside the
* text container.
*
* ~~~~~~ PLOT: total width as a function of height ~~~~~~
*
* The sum of the widths of image and text varies with the height, h, as:
*
* w(h) = txtW(h) + imgW(h)
*
* txtArea
* = ————————————— + imgAspectR * h
* h - txtExtraH
*
*
* w(h)
* ^
* | | .
* | . .
* | . .
* flexW + . .
* | . .
* | . .
* | -
* |
* |———|———|—————|———————————> h
* h1 h0 h2
*
*
* ~~~~~~ FORMULAE: height at which total width is minimum ~~~~~~
*
* The minimum of the function w(h) is at h = h0
*
* ⌈ txtArea ⌉
* h0 = sqrt| —————————— | + txtExtraH
* ⌊ imgAspectR ⌋
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The widths of image and text container at height = h0 are:
*
* txtW(h0) = sqrt( txtArea * imgAspectR )
*
* imgW(h0) = sqrt( txtArea * imgAspectR ) + imgAspectR * txtExtraH
* = txtW(h0) + imgAspectR * txtExtraH
*
* - Note: at if txtExtraH is 0 (i.e. the container has only text), then
* their widths are equal at h0; otherwise the image is wider
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* There are zero, one or two values of h at which w(h) equals the flexbox
* width, flexW. Labelled h1 and h2 above.
*
* ~~~~~~ FORMULAE: height at which total width is equal to flexbox width ~~~~~~
*
* The heights at which the sum of the widths, w(h) equals exactly flexW are:
*
* -b ± sqrt( b^2 - 4ac )
* h2/1 = ——————————————————————
* 2a
*
* where:
* a = imgAspectR
* b = - ( (imgAspectR * txtExtraH) + flexW )
* c = txtArea + (txtExtraH * flexW)
*
* If h1 and h2 are real, then h1 <= h0 <= h2, shown in plot above.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The widths h0, h1 and h2 represent the following visual configuration:
* - h0: intermediate height, maximum free space in the container;
* - h1: minimum height (i.e. wide text and small image), no free space in
* the container;
* - h2: maximum height (i.e. narrow text and large image), no free space in
* the container;
*
* ~~~~~~ SCENARIOS: maximum free space in the flexbox ~~~~~~
*
* Whether there is a solution to the above equation, i.e. whether h1 and h2
* are real, depends on which scenario we have:
*
* 1. If flexW = w(h0), then h1 = h2 = h0
* 2. If flexW < w(h0), then there is no exact solution, i.e. it's impossible
* to fit the text and image inside the flexbox and have them equal heights;
* there is overflow even at h0
* 3. If flexW > w(h0) (as in the graph above), then at h0 there is free space
* in the flexbox and we can choose any height between h1 and h2
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To figure out which of the two elements, text or image, we should
* grow/shrink in case of overflow or too much space, we should determine
* whether the resulting height imbalance (height difference between text and
* image) will be greater if we change the text width or the image width.
*
* ~~~~~~ FORMULAE: text and image height as a function of their width ~~~~~~
*
* The heights of the text container and image as a function of their widths are:
*
* txtArea
* txtH(w) = ——————— + txtExtraH
* w
*
* w
* imgH(w) = ——————————
* imgAspectR
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* - Changing the width of the text container, w, by deltaW (from w to w + deltaW)
* changes its height by
*
* txtArea * deltaW
* txtDeltaH(w, deltaW) = - ————————————————
* w * (w + deltaW)
*
* - Changing the width of the image, w, by deltaW (from w to w + deltaW)
* changes its height by
*
* deltaW
* imgDeltaH(deltaW) = ——————————
* imgAspectR
*
* - Note: the amount of height change we get in the text container depends on
* its current width, but for the image it does not.
* - Note: the amount of height change we get in the text container also depends
* on whether we are growing it or shrinking it, i.e. on the sign of deltaW.
* This is because the narrower the text gets, the more steeply its height
* increases for the same decrease in width, because it is inversely
* proportional to the width.
*
* We need to know whether the difference in height we get by growing/shrinking
* the text by a given amount deltaW is bigger or smaller than the difference
* in height we get by growing/shrinking the image? I.e.:
*
* txtArea ??? 1
* deltaHR = —————————————————————— <>= ——————————
* txtW * (txtW + deltaW) imgAspectR
*
* or alternatively:
*
* txtArea * imgAspectR ???
* deltaHR = ——————————————————————— <>= 1
* deltaW
* txtW^2 * ( 1 + —————— )
* txtW
*
*
* At the initial height of h0: txtW(h0)^2 = txtArea * imgAspectR,
* so the comparison is for:
*
* 1 ???
* deltaHR0 = —————————— <>= 1 => always < 1 for deltaW > 0 and vice versa
* deltaW
* 1 + ——————
* txtW
*
* - Note: at h0 the difference in height when _shrinking_ the text width
* (deltaW < 0) will always be greater than the difference in height when
* growing/shrinking an image, but the opposite is true when _growing_ the
* text width (deltaW > 0). And the more the text grows, the smaller the
* change in height and vice versa. I.e. if we want to minimise the height
* difference between the two when we have to grow or shrink starting at h0,
* we always grow the text and shrink the image.
*
* ~~~~~~ THEREFORE: approach ~~~~~~
*
* 1. If flexW = w(h0), i.e. h1 = h2 = h0:
* => we choose h0 as the height
* 2. If flexW < w(h0), i.e. it's impossible to fit the text and image inside
* the flexbox and have them equal heights:
* => start at h0, as that gives the least amount of overflow, then shrink
* the image by the overflow freeSpace = w(h0) - flexW
* 3. If flexW > w(h0), i.e. at h0 there is free space in the flexbox:
* => choose a height between h1 and h2 that best fits with the guidelines
* maxWidthR and maxFreeR
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* In scenario 3 we can look at the guidelines, maxWidthR and maxFreeR.
*
* ~~~~~~ GUIDELINE: maxWidthR ~~~~~~
*
* ~~~~~~ FORMULAE: height at which text and image width are equal ~~~~~~
*
* The width of the text and image container are equal at height hR0:
*
* txtExtraH + sqrt( txtExtraH^2 + 4 * (h0 - txtExtraH)^2 )
* hR0 = ——————————————————————————————————————————————————————————
* 2
*
* ~~~~~~ FORMULAE: height at which text to image width is maxWidthR ~~~~~~
*
* For heights < hR0, i.e. text becomes wider than the image, at some point the
* ratio of text width to image width becomes maxWidthR. This happens at hR1.
*
* ⌈ 4 * (h0 - txtExtraH)^2 ⌉
* txtExtraH + sqrt| txtExtraH^2 + —————————————————————— |
* ⌊ maxWidthR ⌋
* hR1 = ——————————————————————————————————————————————————————————
* 2
*
* ~~~~~~ FORMULAE: height at which image to text width is maxWidthR ~~~~~~
*
* For heights > hR0, i.e. text becomes narrower than the image, at some point
* the ratio of image width to text width becomes maxWidthR. This happens at hR2.
*
* txtExtraH + sqrt( txtExtraH^2 + 4 * maxWidthR * (h0 - txtExtraH)^2 )
* hR2 = ——————————————————————————————————————————————————————————————————————
* 2
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* - Note: hR1 <= hR0 <= hR2 && hR0 <= h0
* - Note: hR0, hR1 and hR2 are the first (larger) roots of the quadratic
* equation with coefficients:
* a = imgAspectR * R
* b = - imgAspectR * txtExtraH * R
* c = - textArea
* where R = 1 gives hR0, R = maxWidthR gives hR1 and R = 1 / maxWidthR gives hR2
* - The smaller roots of the equation should be negative, so we ignore them
*
* ~~~~~~ GUIDELINE: maxFreeR ~~~~~~
*
* ~~~~~~ FORMULAE: free space in flexbox relative to its width ~~~~~~
*
* The percentage of free space in the container is:
*
* flexW - w(h)
* freeR = ————————————
* flexW
*
*
* txtArea
* flexW - ————————————— - imgAspectR * h
* h - txtExtraH
* = —————————————————————————————————————————
* flexW
*
* ~~~~~~ FORMULAE: height at which relative free space is maxFreeR ~~~~~~
*
* This would be equal to maxFreeR at hF1 and hF2:
*
* -b ± sqrt( b^2 - 4ac )
* hF2/1 = ——————————————————————
* 2a
*
* where:
* a = imgAspectR
* b = - ( (imgAspectR * txtExtraH) + ( flexW * (1 - maxFreeR) ) )
* c = txtArea + ( txtExtraH * flexW * (1 - maxFreeR) )
*
* If hF1 and hF2 are real, then h1 < hF1 <= h0 <= hF2 < h2.
*
* ~~~~~~ THEREFORE: choosing a height in scenario 3 ~~~~~~
*
* So in scenario 3 we can choose any height h between
*
* max(h1, hR1, hF1) < min(h2, hR2, hF2)
*
* This will make the text and image equal height, fitting in the flexbox, and
* if possible, satisfying both maxFreeR and maxWidthR.
*
*/
function customFlexAutoSizeSetVars(data) {
return Promise.resolve(data)
.then(customFlexAutoSizeSaveElementsAndStyles)
.then(customFlexAutoSizeSaveMeasurements)
.then(customFlexAutoSizeSaveCalculations)
.then(customFlexAutoSizeSaveWidths)
.then(customFlexAutoSizeSetWidths)
.then(console.debug)
.catch((err) => {
console.error(err, data);
});
}
function customFlexAutoSizeSaveElementsAndStyles(data) {
// ~~~~ Get the elements
// ~~~~~~~~ text container that contains text and possibly buttons, etc
data.elements.txt = data.flexbox.querySelector(".flex-auto-size-text");
if (data.elements.txt === null) {
// nothing to do
throw "no text container";
}
// ~~~~~~~~ image container that contains or is an image element
data.elements.img = data.flexbox.querySelector(".flex-auto-size-img");
if (data.elements.img === null) {
// nothing to do
throw "no image container";
}
// ~~~~~~~~ the image element itself
// The img element is the child element with img tag, or otherwise svg tag,
// or otherwise, then take the single empty element (that's not a shape
// divider).
data.elements.imgEl =
data.elements.img.querySelector(
"img, svg, :not(:has(>:not(.gspb_shape-divider-container))):not(:is(style,script))",
) || data.elements.img;
// ~~~~ Get the styles
if (data.styles.flexbox === null) {
data.styles.flexbox = customGetCssStyle(data.flexbox);
}
data.styles.txt = customGetCssStyle(data.elements.txt);
data.styles.img = customGetCssStyle(data.elements.img);
return data;
}
function customFlexAutoSizeSaveMeasurements(data) {
// ~~~~ Measure relevant quantities
// - flexW, flexbox width
// - txtArea, textbox area
// - txtExtraH, text container extra height
// - imgAspectR, image aspect ratio
data.debug.fontSize = customGetFontSize(data.styles.txt);
data.debug.textContent = customGetTextContent(data.elements.txt);
const getContainerUsedSize = function (container, style) {
var size = customGetSizeFromChildren(container, null, true);
// add padding and margin of text container
customAddMarginOrPaddingToSize(
size,
customGetMargin(style),
customGetPadding(style),
);
return size;
};
return customGetLoadedImg(data.elements.imgEl).then(() => {
data.measurements.flexW = customGetSize(data.styles.flexbox)[0];
if (!customIsValidPosNum(data.measurements.flexW)) {
throw "failed to measure flexbox width";
}
data.measurements.txtArea = customGetTextArea(
data.styles.txt,
customGetTextContent(data.elements.txt),
);
if (!customIsValidPosNum(data.measurements.txtArea)) {
throw "invalid computed text area";
}
// The flexbox children may have been stretched, so we can't measure their
// size => measure children
// TODO also get size of text nodes
var txtContainerSize = getContainerUsedSize(
data.elements.txt,
data.styles.txt,
);
data.debug.txtContainerSize = txtContainerSize;
data.measurements.txtExtraH =
txtContainerSize[1] - data.measurements.txtArea / txtContainerSize[0];
if (data.measurements.txtExtraH < 0) {
// text area was increased by 10% to account for text wrapping, perhaps
// that's where it comes from? check
if (
txtContainerSize[1] * txtContainerSize[0] <
data.measurements.txtArea / customGetTextArea.correctionFactor
) {
// huh??
throw "got negative extra height in txt container";
}
data.measurements.txtExtraH = 0;
}
// TODO Note, if the image container or its children have margins or
// padding in absolute units, the aspect ratio won't be constant as it
// scales. We assume any padding or margin is relative to the image size.
var imgContainerSize = getContainerUsedSize(
data.elements.img,
data.styles.img,
);
data.debug.imgContainerSize = imgContainerSize;
// ~~~~~~~~ imgAspectR, image aspect ratio ~~~~~~~~
data.measurements.imgAspectR = imgContainerSize[0] / imgContainerSize[1];
if (!customIsValidPosNum(data.measurements.imgAspectR)) {
throw "failed to measure image aspect ratio";
}
return data;
});
}
function customFlexAutoSizeSaveCalculations(data) {
const getTxtW = function (h) {
return data.measurements.txtArea / (h - data.measurements.txtExtraH);
};
const getImgW = function (h) {
return h * data.measurements.imgAspectR;
};
data.calculations.h0 =
Math.sqrt(data.measurements.txtArea / data.measurements.imgAspectR) +
data.measurements.txtExtraH;
if (!customIsValidPosNum(data.calculations.h0)) {
throw "invalid h0";
}
// heights satisfying w(h) <= flexW
[data.calculations.h2, data.calculations.h1] = customQuadraticRoots(
data.measurements.imgAspectR,
-(
data.measurements.imgAspectR * data.measurements.txtExtraH +
data.measurements.flexW
),
data.measurements.txtArea +
data.measurements.txtExtraH * data.measurements.flexW,
);
// heights satisfying maxWidthR
if (data.settings.maxWidthR > 0) {
[data.calculations.hR0, _] = customQuadraticRoots(
data.measurements.imgAspectR,
-data.measurements.imgAspectR * data.measurements.txtExtraH,
-data.measurements.txtArea,
);
[data.calculations.hR1, _] = customQuadraticRoots(
data.measurements.imgAspectR * data.settings.maxWidthR,
-data.measurements.imgAspectR *
data.measurements.txtExtraH *
data.settings.maxWidthR,
-data.measurements.txtArea,
);
[data.calculations.hR2, _] = customQuadraticRoots(
data.measurements.imgAspectR / data.settings.maxWidthR,
(-data.measurements.imgAspectR * data.measurements.txtExtraH) /
data.settings.maxWidthR,
-data.measurements.txtArea,
);
}
// heights satisfying maxFreeR
if (data.settings.maxFreeR >= 0) {
[data.calculations.hF2, data.calculations.hF1] = customQuadraticRoots(
data.measurements.imgAspectR,
-(
data.measurements.imgAspectR * data.measurements.txtExtraH +
data.measurements.flexW * (1 - data.settings.maxFreeR)
),
data.measurements.txtArea +
data.measurements.txtExtraH *
data.measurements.flexW *
(1 - data.settings.maxFreeR),
);
}
// maximum and minimum heights
data.calculations.hMin = Math.max(
...[
data.calculations.h1,
data.calculations.hR1,
data.calculations.hF1,
].filter((v) => !isNaN(v)),
);
data.calculations.hMax = Math.min(
...[
data.calculations.h2,
data.calculations.hR2,
data.calculations.hF2,
].filter((v) => !isNaN(v)),
);
// text and image widths at the various relevant heights
data.calculations.tw0 = getTxtW(data.calculations.h0);
data.calculations.tw1 = getTxtW(data.calculations.h1);
data.calculations.tw2 = getTxtW(data.calculations.h2);
data.calculations.twHMin = getTxtW(data.calculations.hMin);
data.calculations.twHMax = getTxtW(data.calculations.hMax);
data.calculations.iw0 = getImgW(data.calculations.h0);
data.calculations.iw1 = getImgW(data.calculations.h1);
data.calculations.iw2 = getImgW(data.calculations.h2);
data.calculations.iwHMin = getImgW(data.calculations.hMin);
data.calculations.iwHMax = getImgW(data.calculations.hMax);
// free space at h0
data.calculations.freeSpace0 =
data.measurements.flexW - data.calculations.tw0 - data.calculations.iw0;
// some sanity checks
// if any of then is NaN, the comparison would be false, so we don't need to
// check
if (isNaN(data.calculations.h1) ^ isNaN(data.calculations.h2)) {
throw "one and only one of h1 or h2 is real";
}
if (isNaN(data.calculations.hR1) ^ isNaN(data.calculations.hR2)) {
throw "one and only one of hR1 or hR2 is real";
}
if (isNaN(data.calculations.hF1) ^ isNaN(data.calculations.hF2)) {
throw "one and only one of hF1 or hF2 is real";
}
if (data.calculations.h1 > data.calculations.h0) {
throw "h1 > h0";
}
if (data.calculations.h0 > data.calculations.h2) {
throw "h0 > h2";
}
if (data.calculations.hR0 > data.calculations.h0) {
throw "hR1 > h0";
}
if (data.calculations.hR1 > data.calculations.hR0) {
throw "hR1 > hR0";
}
if (data.calculations.hR0 > data.calculations.hR2) {
throw "hR0 > hR2";
}
if (data.calculations.hF1 > data.calculations.hF2) {
throw "hF1 > hF2";
}
if (data.calculations.h1 > data.calculations.hF1) {
throw "h1 > hF1";
}
if (data.calculations.h2 < data.calculations.hF2) {
throw "h2 < hF2";
}
if (data.calculations.hMax < data.calculations.hMin) {
throw "hMax < hMin";
}
return data;
}
function customFlexAutoSizeSaveWidths(data) {
if (data.calculations.freeSpace0 <= 0) {
data.debug.scenario = 1 + (data.calculations.freeSpace0 < 0);
// scenario 1 or 2
data.widths.txt = data.calculations.tw0;
// shrink image if needed, remember freeSpace0 is negative (or 0)
// if abs(freeSpace0) > iw0, then this will fail, which is fine: we abort
// and leave it at the default settings as clearly there's too much text or
// the image is too wide for the size of the flexbox
data.widths.img = data.calculations.iw0 + data.calculations.freeSpace0;
} else {
// scenario 3
data.debug.scenario = 3;
// TODO which one
data.widths.txt = data.calculations.twHMin;
data.widths.img = data.calculations.iwHMin;
}
if (!customIsValidPosNum(data.widths.txt)) {
throw "invalid computed text width";
}
if (!customIsValidPosNum(data.widths.img)) {
throw "invalid computed image width";
}
return data;
}
function customFlexAutoSizeSetWidths(data) {
data.flexbox.style.setProperty(
"--flex-auto-size-txt-width",
// customPx2Em(data.styles.root, data.widths.txt) + "rem",
data.widths.txt + "px",
);
data.flexbox.style.setProperty(
"--flex-auto-size-img-width",
// customPx2Em(data.styles.root, data.widths.img) + "rem",
data.widths.img + "px",
);
return data;
}
/*
* Iterate over all the flex auto-size containers whose direction is row and
* set the variables for them.
*/
window.addEventListener("DOMContentLoaded", function () {
// global parameters: avoid getting them now, only do so if there is at least
// one flexbox to process on the page
var settings = null;
var rootStyle = null;
var abort = false;
document.querySelectorAll(".flex-auto-size").forEach((el) => {
if (abort) {
return;
}
const flexStyle = customGetCssStyle(el);
if (flexStyle.getPropertyValue("flex-direction") === "column") {
return;
}
if (settings === null) {
rootStyle = customGetCssStyle(document.querySelector(":root"));
settings = {
maxWidthR:
parseFloat(
rootStyle.getPropertyValue("--flex-auto-size-max-width-r"),
) || -1,
maxFreeR:
parseFloat(
rootStyle.getPropertyValue("--flex-auto-size-max-free-r"),
) || -1,
};
if (
!customIsValidNum(settings.maxWidthR) ||
!customIsValidNum(settings.maxFreeR) ||
(settings.maxWidthR > 0 && settings.maxWidthR < 1) ||
settings.maxFreeR > 1
) {
console.error("Invalid flex auto-size settings");
abort = true;
return;
}
}
var data = {
flexbox: el,
settings: settings,
elements: {
txt: null,
img: null,
imgEl: null,
},
measurements: {
flexW: NaN,
txtArea: NaN,
txtExtraH: NaN,
imgAspectR: NaN,
},
calculations: {
h0: NaN,
h1: NaN,
h2: NaN,
hF1: NaN,
hF2: NaN,
hR0: NaN, // not needed; for debugging only
hR1: NaN,
hR2: NaN,
hMin: NaN,
hMax: NaN,
tw0: NaN,
tw1: NaN,
tw2: NaN,
twHMin: NaN,
twHMax: NaN,
iw0: NaN,
iw1: NaN,
iw2: NaN,
iwHMin: NaN,
iwHMax: NaN,
freeSpace0: NaN,
},
widths: {
txt: NaN,
img: NaN,
},
styles: {
root: rootStyle, // not needed
flexbox: flexStyle,
txt: null,
img: null,
},
debug: {},
};
customFlexAutoSizeSetVars(data);
});
});
function customIsValidNum(n) {
return !isNaN(n) && Math.abs(n) !== Infinity;
}
function customIsValidPosNum(n) {
return customIsValidNum(n) && n > 0;
}
function customIsValidNonNegNum(n) {
return customIsValidNum(n) && n >= 0;
}
function customGetCssStyle(el, prop) {
const style = window.getComputedStyle(el, null);
if (prop !== undefined) {
return style.getPropertyValue(prop);
}
return style;
}
function customGetCanvasFont(style) {
const fontWeight = style.getPropertyValue("font-weight") || "normal";
const fontSize = style.getPropertyValue("font-size") || "16px";
const fontFamily = style.getPropertyValue("font-family") || "Times New Roman";
return `${fontWeight} ${fontSize} ${fontFamily}`;
}
function customIsInline(style) {
const display = style.getPropertyValue("display");
return display === "contents" || display.includes("inline");
}
function customGetMargin(style) {
return customMapPxStr2Float([
style.getPropertyValue("margin-top"),
style.getPropertyValue("margin-right"),
style.getPropertyValue("margin-bottom"),
style.getPropertyValue("margin-left"),
]);
}
function customGetPadding(style) {
return customMapPxStr2Float([
style.getPropertyValue("padding-top"),
style.getPropertyValue("padding-right"),
style.getPropertyValue("padding-bottom"),
style.getPropertyValue("padding-left"),
]);
}
function customGetSize(style) {
return customMapPxStr2Float([
style.getPropertyValue("width"),
style.getPropertyValue("height"),
]);
}
function customGetOffsetSize(element) {
return [element.offsetWidth, element.offsetHeight];
}
function customAddMarginOrPaddingToSize(size, ...arrays) {
arrays.forEach((marginOrPadding) => {
size[0] += marginOrPadding[1] + marginOrPadding[3];
size[1] += marginOrPadding[0] + marginOrPadding[2];
});
}
function customGetSizeFromChildren(
container,
childSelector = null,
includeMargin = false,
) {
var totalSize = [0, 0];
var currInlineW = 0;
var currInlineH = 0;
const addInlineSize = function (w, h) {
currInlineW += w;
if (h > currInlineH) {
currInlineH = h;
}
};
const addBlockSize = function (w, h) {
if (totalSize[0] < w) {
totalSize[0] = w;
}
totalSize[1] += h;
};
const finishInlineGroup = function () {
addBlockSize(currInlineW, currInlineH);
currInlineW = currInlineH = 0;
};
var children;
if (childSelector === null) {
children = Array.from(container.children);
} else {
children = container.querySelectorAll(`:scope > :is(${childSelector})`);
}
children.forEach((child) => {
let style = customGetCssStyle(child);
let size = customGetSize(style);
if (includeMargin) {
let margins = customGetMargin(style);
size[0] += margins[1] + margins[3];
size[1] += margins[0] + margins[2];
}
// for inline elements, add widths and take max height;
// otherwise add height and take max width
if (customIsInline(style)) {
addInlineSize(size[0], size[1]);
} else {
finishInlineGroup();
addBlockSize(size[0], size[1]);
}
});
finishInlineGroup();
return totalSize;
}
function customGetTextContent(container) {
var textContent = "";
var textChildren = Array.from(
container.querySelectorAll(
":scope :not(:has(> *)):not(:empty, style, script)",
),
);
Array.from(container.childNodes).forEach((child) => {
if (child.nodeType === Node.TEXT_NODE) {
textChildren.push(child);
}
});
textChildren.forEach((child) => {
textContent += child.textContent.trim();
});
return textContent;
}
function customGetLoadedImg(imgEl) {
return new Promise((resolve) => {
if (imgEl.tagName === "IMG") {
// prevent race condition where the img may load between us checking
// complete and setting onload
imgEl.onload = function () {
resolve(imgEl);
};
if (imgEl.complete) {
resolve(imgEl);
}
return;
}
resolve(imgEl);
});
}
function customGetImgSize(el) {
const getImgTagSize = function (imgEl) {
return [
imgEl.width || imgEl.naturalWidth,
imgEl.height || imgEl.naturalHeight,
];
};
return new Promise((resolve) => {
switch (el.tagName.toLowerCase()) {
case "img":
const width = el.getAttribute("width");
const height = el.getAttribute("height");
if (width !== null && height !== null) {
resolve([parseFloat(width), parseFloat(height)]);
} else {
// get it when the image loads
customGetLoadedImg.then((imgEl) => {
resolve(getImgTagSize(imgEl));
});
}
break;
case "svg":
resolve([el.width.baseVal.value, el.height.baseVal.value]);
break;
default:
const r = el.getBoundingClientRect();
resolve([r.width, r.height]);
}
});
}
function customGetTextWidth(style, text) {
// re-use canvas object for better performance
const canvas =
customGetTextWidth.canvas ||
(customGetTextWidth.canvas = document.createElement("canvas"));
const context = canvas.getContext("2d");
context.font = customGetCanvasFont(style);
const metrics = context.measureText(text);
return metrics.width;
}
function customGetTextArea(style, text) {
const txtWSingle = customGetTextWidth(style, text);
if (!customIsValidPosNum(txtWSingle)) {
return null;
}
const txtLineH = customGetLineHeight(style);
if (!customIsValidPosNum(txtLineH)) {
return null;
}
// add a small increasing factor to take into account wasted space due to
// wrapping
return txtWSingle * txtLineH * customGetTextArea.correctionFactor;
}
customGetTextArea.correctionFactor = 1; // XXX 1.1;
function customGetFontSize(style) {
return customPxStr2Float(style.getPropertyValue("font-size"));
}
function customGetLineHeight(style) {
const lh = style.getPropertyValue("line-height");
if (lh !== "normal") {
return customPxStr2Float(lh);
}
return 1.14 * customGetFontSize(style); // most browser's default
}
function customPxStr2Float(pxSize) {
return parseFloat(pxSize.slice(0, -2));
}
function customMapPxStr2Float(pxSizes) {
return pxSizes.map(customPxStr2Float);
}
function customPx2Em(style, pxSize) {
const fs = customGetFontSize(style);
return pxSize / fs;
}
function customMapPx2Em(style, pxSizes) {
const fs = customGetFontSize(style);
return pxSizes.map(function (pxSize) {
pxSize / fs;
});
}
function customUnitStr2Px(style, str) {
var dummy = customUnitStr2Px.dummy;
if (dummy === undefined) {
dummy = document.createElement("div");
dummy.style.setProperty("position", "absolute");
dummy.style.setProperty("top", "0");
dummy.style.setProperty("z-index", "-9999");
dummy.style.setProperty("visibility", "hidden");
document.body.append(dummy);
customUnitStr2Px.dummy = dummy;
customUnitStr2Px.dummyStyle = customGetCssStyle(dummy);
}
var dummyStyle = customUnitStr2Px.dummyStyle;
const unit = str.replace(/^[0-9]+/, "");
switch (unit) {
case "%":
return NaN;
case "em":
case "ex":
case "ch":
dummy.style.setProperty("font-size", style.getPropertyValue("font-size"));
}
dummy.style.setProperty("width", str);
return customPxStr2Float(dummyStyle.getPropertyValue("width"));
}
function customQuadraticRoots(a, b, c) {
let z = Math.sqrt(b * b - 4 * a * c);
return [(-b + z) / (2 * a), (-b - z) / (2 * a)];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment