I'm having a serious CSS challenge on a small project I'm building:
I have a <main>
element which is set as flexbox of row. inside are 3 children:
:root {
--clr-light-text: #f2f2f2;
--clr-dark-text: #48484a;
--shadow-default: 0px 2px 8px rgba(0, 0, 0, 0.2);
--vid-container-h: 0px;
color: var(--clr-light-text);
font-family: 'Poppins', sans-serif;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
list-style: none;
text-decoration: none;
}
h1,
h2,
h3,
h4 {
font-weight: 400;
}
body {
background-color: var(--clr-dark-text);
text-align: center;
overflow-x: hidden;
scroll-behavior: smooth;
}
.glass {
background-image: linear-gradient( 135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0));
backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: var(--shadow-default);
border-radius: 0.5rem;
}
main {
display: flex;
justify-content: center;
padding: 0 1rem;
gap: 2rem;
}
.main-container {
background-color: hsl(0, 0%, 75%);
padding-bottom: 10rem;
position: relative;
}
.weather-box {
width: clamp(13.5rem, 18%, 20rem);
display: flex;
flex-direction: column;
justify-content: space-evenly;
padding: 0 1em 1em 1em;
}
#weather-icon {
margin: -15% -10%;
}
.weather-details {
display: flex;
flex-direction: column;
justify-content: space-between;
}
#forecast,
#temp,
#humidity {
display: flex;
flex-direction: column;
align-items: center;
}
#temp {
margin-bottom: 1em;
font-weight: 200;
}
#temp-num {
font-size: 3em;
}
#humid {
font-size: 1.5em;
}
#humid-value {
font-size: 1.5em;
font-weight: 200;
}
#humid-value img {
max-width: 1em;
}
#forecast-desc {
font-size: 2.5em;
font-weight: 400;
}
.playlist-box {
width: clamp(13.5rem, 18%, 20rem);
display: flex;
align-items: center;
flex-direction: column;
padding: 1rem 0.5em;
flex-shrink: 0;
}
.playlist-box h3::after {
content: '';
width: 70%;
height: 1px;
background-color: rgba(255, 255, 255, 0.3);
border-radius: 100vmax;
display: block;
margin: 1em auto;
}
#playlist {
display: grid;
width: 100%;
padding: 1em;
overflow-y: scroll;
scroll-behavior: smooth;
}
#playlist li {
margin-bottom: 1rem;
width: 100%;
padding: 1rem;
border: 1px solid rgba(255, 255, 255, 0);
}
#playlist li:hover,
#playlist li:focus {
background-image: linear-gradient( 135deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0));
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: var(--shadow-default);
border-radius: 0.5rem;
}
.song-title {
margin-bottom: 0.5em;
}
.vid-thumb {
width: 100%;
/* object-position: center;
object-fit: cover; */
}
.video-container {
align-self: flex-start;
padding: 1em;
}
#song-frame {
position: relative;
overflow: hidden;
width: 100%;
padding-top: 56.25%;
}
#song-frame iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<div >
<main>
<aside >
<div id="forecast">
<img id="weather-icon" src="http://openweathermap.org/img/wn/[email protected]" alt="Weather Icon" />
<span id="forecast-desc">(--)</span>
</div>
<div >
<div id="temp">
<span id="temp-num">0°c</span>
<span id="feels-like">feels like 0°c</span>
</div>
<div id="humidity">
<span id="humid">Humidity</span>
<div id="humid-value">
<span id="humid-num">0%</span>
</div>
</div>
</div>
</aside>
<div >
<div id="song-frame">
<iframe src="https://www.youtube.com/embed/oG08ukJPtR8" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" width="1024" height="576" frameborder="0"></iframe>
</div>
</div>
<aside >
<h3>Browse Playlist:</h3>
<ul id="playlist">
<li>
<h4>Song Title</h4>
<img src="https://i.ytimg.com/vi/ru0K8uYEZWw/hqdefault.jpg" alt="" />
</li>
<li>
<h4>Song Title</h4>
<img src="https://i.ytimg.com/vi/pkCyfBibIbI/hqdefault.jpg" alt="" />
</li>
</ul>
</aside>
</main>
</div>
I applied to both <aside>
elements to have a responsive width with the following width: clamp(13.5rem, 18%, 20rem)
. The div in the center uses the rest of the available width of the viewport. Generally, the layout kinda works.
The weather-container
's clamp works just fine. The playlist-container
though is able to shrink to less than 13.5rem (216px) and in some screen sizes I'm left with uneven containers in the sides.
The interesting part is that problem is somehow connected to the <img>
thumbnails. The set width for them is 100%. If I cancel it out, the container behaves correctly but the thumbnails are cut off.
- setting a fixed
width
value doesn't work. - setting a
min-width
to the element doesn't work. - setting
flex-shrink: 0;
to the element doesn't work. - messing with
flex-basis
also didn't work for me. - changing the
<img>
to a<div>
withbackground-image
instead produces the same result.
Would love to get over this problem, thank you.
Edit: I've produced a CodePen which recreates the problem: https://codepen.io/xandertem/pen/XWZLaVR
Try going to responsive mode and see the right section shrinking around <560px.
CodePudding user response:
For reasons I don't understand clamp in the width setting of flex just does not seem to work.
Also to automatically have the two asides with the height of the middle item you could use grid.
To get round what seems to be the clamp problem this snippet separates out the ranges by using min and max width media queries [when 18% is 13.5rem the overall width is 75rem and so on).
* {
box-sizing: border-box;
}
main {
display: grid;
grid-template-columns: 18% 1fr 18%;
width: 100vw;
}
@media screen and (max-width: 75rem) {
main {
grid-template-columns: 13.5rem 1fr 13.5rem;
}
}
@media screen and (min-width: 111.111rem) {
main {
grid-template-columns: 20rem 1fr 20rem;
}
}
main {
padding: 0 1rem;
gap: 2rem;
}
.weather-container {
display: flex;
flex-direction: column;
justify-content: space-evenly;
padding: 0 1em 1em 1em;
}
.video-container {
padding: 1em;
}
.playlist-container {
display: flex;
align-items: center;
flex-direction: column;
padding: 1rem 0.5em;
}
.vid-thumb {
width: 100%;
/* object-position: center;
object-fit: cover; */
}
<main>
<div >
...divs...
</div>
<div >
<div>
<iframe>...</iframe>
</div>
</div>
<div >
<h3>Browse Playlist:</h3>
<ul>
<li>
<h4>Song Title</h4>
<img src="https://i.ytimg.com/vi/example.jpg" alt="">
</li>
<li>etc...</li>
</ul>
</div>
</main>
CodePudding user response:
Adding flex-shrink: 0
to the aside
(.playlist-box
) solves the problem.
You should probably add the same rule to the other aside
(.weather-box
), even though you don't need it, just in case the type of content in that container ever changes. As you can see, images and videos make a difference.