why is my html/css layout behaving this way?

to preface, i've already figured out the fix to this. I'm still curious though as to why the elements are laid out this way. why did 3 of the empty divs get their own row, meanwhile the other 3 are hidden behind the row of images. Also, what did the empty divs even base their 100% height off of ? thanks. https://codepen.io/Joseph-Huff-the-scripter/pen/bGyMvJr
12 Replies
forlorn_died
forlorn_died2w ago
I think they are overflowing that is why they are stacked like thats why the orange is a bit offset to the image original position Also container is set to grid Idk its hard to guess You can try inside your *{} to give all the elements a border That way you can know thier frames
clevermissfox
clevermissfox2w ago
i prefer outline or background over border since it doesnt take up space but is a good suggestion to help visualize what is what. You can also open your dev tools and turn on the grid. looks like you have some overflow out of the bottom. Is the second screenshot more what you intended? if so its your height: 100% is doing nothing because its parent (.card) has no height declared. here i gave the blockers an aspect-ratio;
No description
No description
clevermissfox
clevermissfox2w ago
also its not great practice to include empty divs for decorative elements; this is where pseudo-elements shine and the DOM isnt littered* with empty divs
joey //
joey //2w ago
no the 2nd screenshot isnt what i intended. i intended to have the empty divs block cover the images, which i ended up figuring out. i just didnt understand exactly why it rendered that way in the fist place . is the first row of divs overflowing into the 2nd row, and the 2nd row overflowing into what appears as a 3rd row ? and are they the size of the image because the 100% refers to .card and cards width is being defined by its content (in this case the image inside ) ? thanks for helping me clear it up
clevermissfox
clevermissfox2w ago
Let's simplify it. Let's break it down to one card. You have a parent (the grid) and inside the grid you have one .card. within the card there are two children- the image and the blocker. Since you haven't set the blocker to position absolute, it flows in the normal block formatting context. First comes the image , then the blocker is underneath the inage. You haven't set position absolute or anything on the blocker that tells the card you want it's contents to layer one on top of each other. So by default they stack , just like two paragraph elements would, first one paragraph then that paragraph ends and the second begins. They aren't layered on top of one another. The parent grid is only setting the cards into cells, the cards contents know nothing about the grid. They are just following their parent to try to fit into the space that's defined for .card. Because of the fixed height of the grid, yes everything is overflowing. A much easier way would be to remove the blocker div , and just set a bg on the card. Or use a pseudo element on the card if you want that color on top of the image.
joey //
joey //2w ago
i dont know how to do the psuedo route but that first idea is a good one and would simplify things a bit
clevermissfox
clevermissfox2w ago
You must learn pseudo-elements! The only difference from any other element is the selector ::before or ::after and that you must include a content:'' property, even if it's empty. Other than that it works like any other child of your element. A common misconception is that pseudo-elements are before or after the elemrnt itself. Taking your card as an example (you can also verify this in the dev tools) , the pseudo element lives here
<div class="card">
::before

<img src="https://xyz.png" >

::after
</div>
<div class="card">
::before

<img src="https://xyz.png" >

::after
</div>
NOT
::before
<div class="card">
<img src="https://xyz.png" >
</div>
::after
::before
<div class="card">
<img src="https://xyz.png" >
</div>
::after
So it's treated as a child of the card. Just don't forget the content property.
.card {
position: relative
/* since we are setting pos absolute on the ::before */
isolation: isolate;
/*to prevent the negative zindex of the ::before from escaping outside the card
}

.card::before {
content: ' ';
position: absolute;
inset:0;
background-color: orange;
z-index: -1;
}
.card {
position: relative
/* since we are setting pos absolute on the ::before */
isolation: isolate;
/*to prevent the negative zindex of the ::before from escaping outside the card
}

.card::before {
content: ' ';
position: absolute;
inset:0;
background-color: orange;
z-index: -1;
}
clevermissfox
clevermissfox2w ago
Kevin Powell
YouTube
Before and After pseudo elements explained - part one: how they work
The before and after pseudo elements are super useful part of CSS, but are often misunderstood. This is part of a three-part series where I look at how they work, and cool stuff we can do with them. In this video, I focus on what ::before and ::after even are and how we can use them, and even why we use the double colon before them, instead of ...
joey //
joey //2w ago
kevo is the man with the plan i will definitely check that video out
forlorn_died
forlorn_died2w ago
Maybe learn the other basics first before pseudo code, they can be hard to control specially in position: property where you want them as a tool for overlaying Or filter, or any sort
clevermissfox
clevermissfox2w ago
I know what you mean but using inset:0 and using a pseudo element as a background colour is a good starting point to get acquainted with them in my opinion. If you can just use inset 0 you don’t have to move it around at all and it becomes the same size as its parent.
forlorn_died
forlorn_died2w ago
Now thats new, thanks for the tip, ill save if for later 🙏 Omg, i just used it now and it worked What a lifesaver