I'm working on a layout where I have a vertical flex container of screen height that contains a dynamic number of cards. Each card should take up the full width of the container and has an image that should shrink if the vertical parent container overflows in the Y direction. To achieve this, I'm using overflow: hidden on both the container and the card.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
display: flex;
height: 100dvh;
overflow-y: hidden;
resize: vertical; /* For example purpose */
}
.sidebar {
position: relative;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 0.5rem;
height: 100%;
width: fit-content;
max-width: 9rem;
padding: 0.5rem;
border: 1px solid black;
overflow-y: hidden;
z-index: 0;
}
.card {
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
width: 100%;
z-index: 0;
border: 1px solid black;
padding: 0.25rem;
}
.card .image-container {
display: flex;
flex-shrink: 1;
width: 100%;
overflow: hidden;
}
.card .image-container img {
width: 100%;
object-fit: contain;
}
.card p {
flex: 0 0 auto;
}
.card .message {
position: absolute;
bottom: 25%;
left: 90%;
padding: 0.25rem 0.5rem;
border-radius: 20%;
background-color: red;
z-index: 50;
}
<div class="container">
<aside class="sidebar">
<div class="card">
<!-- image container is required for actual use-case -->
<div class="image-container">
<img src="https://picsum.photos/200" alt="200x200 image" />
</div>
<p>Some Text</p>
<div class="message">Hello</div>
</div>
</aside>
</div>
The issue arises when I try to add an absolutely positioned div (a .message element) inside each card. This element needs to be positioned partially outside the card, but it's getting hidden due to the overflow: hidden property on the card.
I am not able to think of how to get a solution for this particular requirement.
To get the images to shrink, position them absolutely. Absolute positioning is the magic way to prevent the intrinsic dimensions of an image from affecting a layout, or, to say it another way, to ensure that the layout determines the size of an image (eg. shrinks it). There will then be no reason to set overflow: hidden
and your messages can overflow outside the box.
Does this look like the layout you are trying to achieve? I have illustrated sidebars with different numbers of cards, and some with object-fit: contain
and some with object-fit: cover
.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
display: flex;
height: 80vh;
width: 80vw;
margin-top: 10vh;
margin-left: 10vw;
background: yellow;
gap: 5em;
}
.sidebar {
position: relative;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: flex-start;
gap: 0.5rem;
height: 100%;
width: 9rem;
padding: 0.5rem;
background: pink;
}
.card {
flex: 1;
padding: 0.25rem;
background: white;
display: flex;
flex-direction: column;
gap: 0.25rem;
position: relative;
}
.card .image-container {
display: flex;
flex: 1;
background: #f0f0f0;
position: relative;
}
.card .image-container img {
position: absolute;
height: 100%;
width: 100%;
object-fit: contain;
display: block;
}
.card p {
flex: 0 0 auto;
align-self: center;
}
.card .message {
position: absolute;
bottom: 25%;
left: 90%;
padding: 0.25rem 0.5rem;
border-radius: 4px;
background-color: red;
z-index: 50;
}
.s2 .card .image-container img {
object-fit: cover;
}
<div class="container">
<aside class="sidebar">
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
</aside>
<aside class="sidebar">
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>contain</p>
<div class="message">Hello</div>
</div>
</aside>
<aside class="sidebar s2">
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
</aside>
<aside class="sidebar s2">
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
<div class="card">
<div class="image-container">
<img src="https://picsum.photos/200">
</div>
<p>cover</p>
<div class="message">Hello</div>
</div>
</aside>
</div>
After running this snippet, use the full page link to test the responsive behaviour.