Reputation: 99
I have a parent <div>
of unknown size and I would like to create a child <div>
of the size of the biggest square which can be contained in the parent and center this square in the middle of the parent. Is it possible with HTML
and CSS
?
I am aware of max-width
and max-height
but do not know how to ensure the aspect-ratio.
I want to be able to do something like this:
.frame {
height: 80%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.square {
width: 750px;
height: 750px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.back {
width: 100%;
}
.front {
width: 70.5%;
top: 23.965%;
position: absolute;
}
<div class="frame">
<div class="square">
<img class="back" src="back.png">
<img class="front" src="front.png">
</div>
</div>
But in the square
I want the width and height set based on its parent frame
as described. The parent frame
can be both landscape or portrait.
Upvotes: 0
Views: 925
Reputation: 1335
This was not possible for a long time; as padding-top:100%
and aspect-ratio:1/1
are limited to the width (and not the height) of the container.
BUT It is now possible; keep reading...
███ <- square fills the width correctly
███
░░░ <- outer box (portrait)
░░░
███████████ \
███████████ } <- outer box (landscape) stops here
███████████ / but square overfloweth
███████████
███████████
███████████
Technically, the aspect-ratio doesn't fill the width, so much as the "block direction", which in western languages is always the width...
However, we can change the writing-mode
property to get the block direction to be height, like so:
writing-mode: vertical-lr
███░░░ <- outer box (landscape)
███░░░
^- square fills the height correctly
███████
███████
███████
███████
^---^
`---- outer box (portrait) stops here, but square overfloweth
So now we have the opposite problem, it works in landscape but not portrait.
Using the right combination of media queries it should be possible to switch the writing mode at the exact dimensions it switches from portrait to landscape.
html, body {
margin: 0;
}
*, *:before, *:after {
box-sizing: border-box;
}
.bounds-outer {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
}
.bounds-inner {
writing-mode: vertical-rl;
width: 100%;
max-width: 90%;
height: 100vh;
border: 1px dashed black;
display: flex;
align-items: center;
}
.a {
position: relative;
flex: 1 0 1px;
background: red;
padding-block-start: 100%;
}
.b {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
color: white;
writing-mode: horizontal-tb;
}
/* this media query depends on layout */
@media (max-aspect-ratio: 10/9) {
.bounds-inner {
writing-mode: horizontal-tb;
}
}
<div class="bounds-outer">
<div class="bounds-inner">
<div class="a">
<div class="b">
Hi
</div>
</div>
</div>
</div>
NOTE: Your media queries will depend on the size of the box. Verified in Chrome, Firefox and Safari.
Upvotes: 3