Amazing issue: position: absolute is affected by the parent's overflow: hidden? - css

I found out an amzing case where the position: absolute element is hidden.
You can also see demo here.
.grand {
float: left;
overflow: hidden;
/* transform: scale(1,1); */
}
.parent {
width: 50px;
height: 50px;
background-color: gold;
overflow: hidden;
transform: rotate(0deg);
}
.child {
position: absolute;
top: 20px;
left: 10px;
width: 100px;
height: 100px;
background-color: pink;
}
<div class="grand">
<div class="parent">
<div class="child"></div>
</div>
</div>
The issue is: .grand is set overflow: hidden and .parent is set transform: rotate(0deg), which make the child hidden. Normally, the .child with position: absolute; is not afftected by its parent elements not set position: relative. So what is the reason? Thank you very much!

Likely, it's the fact that .parent has a transform, which makes it the containing block for the absposed element the same way position: relative does.

Related

Cannot get css hover to action

I've been struggling to hover to work. All this should do is have a red container div and when you hover it, a black inner div drops down from the top to block the container. I must be doing something basic wrong here.
HTML:
<div class="container">
<div class="inner" />
</div>
CSS:
.container {
position: relative;
width: 200px;
height: 200px;
background: red;
}
.inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
max-height: 0;
background: black;
transition: max-height 2s ease-out;
overflow: hidden;
}
.container:hover .inner {
max-height: 200px;
}
As mentioned by Temani Afif, this was nothing more than missing a height.

CSS Parent div height is more than child div when child position is relative and its top value is negative. How to contract the height of parent?

Here is the JSFIddle
I understand that the extra-height is the height of the child-2 div if it was positioned static.
How can we contract the parent height so that it fits the child divs?
HTML:
<div class="parent">
<div class="child-1">
</div>
<div class="child-2">
</div>
</div>
CSS:
.parent {
width: 200px;
background-color: #ddd;
}
.child-1 {
width: 100%;
height: 40px;
background-color: #aaa;
}
.child-2 {
position: relative;
left: 50%;
transform: translateX(-50%);
top: -20px;
width: 40px;
height: 40px;
background-color: #555;
}
The parent has extended hight because postion:relative elements still occupy their original space in normal flow.
In order to contract the parent you've to take it out if normal flow, one way to do this is to apply position:absolute to the child, and then position it relative to the parent by giving it position:relative
.parent {
position: relative;
width: 200px;
background-color: #ddd;
}
.child-1 {
width: 100%;
height: 40px;
background-color: #aaa;
}
.child-2 {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: 40px;
background-color: #555;
}
<div class="parent">
<div class="child-1">
</div>
<div class="child-2">
</div>
</div>

CSS: placing absolute positioned element so that it touches its parent from outside

I want the absolute positioned child touch its parent from outside like this:
.parent {
background: #aaffaa;
width: 200px;
height: 200px;
margin-left: 150px;
display: flex;
align-items: center;
position: relative;
}
.child {
background: #ffaaaa;
width: 100px; // actually unknown, here for demo purposes
height: 100px;
position: absolute;
left: 0;
transform: translate(-100%);
}
<div class="parent">
<div class="child"></div>
</div>
The problem: I can't use the transform property, because it's already in use in a keyframe animation, the element may or may not be position: absolute. Is there some elegant solution to this?
Sure there is! There is just 1 line missing in your code.
You just need to use right:100% and it will be just fine.
.parent {
background: #aaffaa;
width: 200px;
height: 200px;
margin-left: 150px;
display: flex;
align-items: center;
position: relative;
}
.child {
background: #ffaaaa;
width: 100px;
height: 100px;
position: absolute;
right: 100%;
}
<div class="parent">
<div class="child"></div>
</div>

css z-index issue with nested elements

I have 3 HTML elements that I want to order on the z plane:
.bank {
width: 200px;
height: 200px;
background-color: grey;
position: absolute;
z-index: 100;
transform: translateY(10%);
}
.card {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left: 50px;
top: 50px;
z-index: 300;
}
.button {
width: 50px;
height: 50px;
background-color: green;
position: absolute;
left: 30px;
top: 50px;
z-index: 200;
}
<div class="bank">
bank
<div class="card">card</div>
</div>
<div class="button">button</div>
I want the button to be on top of the bank but behind the card. But the button is always on top of both the bank and the card no matter what I try.
Edit: I noticed that removing z-index and transform from '.bank' solves it, but I need the transform property. What can I do?
What may cause it not to work? Thanks
Don't specify any z-index to .bank to avoid creating new stacking context and simply adjust the z-index of the other elements. This will work because all the 3 elements belong to the same stacking context so you can specify any order you want.
.bank {
position:relative;
background: red;
width: 500px;
height: 200px;
}
.card {
position: absolute;
top:0;
z-index: 2;
height: 100px;
width: 400px;
background: blue;
}
.button {
position: absolute;
top: 0;
z-index: 1;
height: 150px;
width: 450px;
background: yellow;
}
.container {
position: relative;
}
<div class="container">
<div class="bank">
<div class="card"></div>
</div>
<div class="button"></div>
</div>
UPDATE
Considering you code, the only way is to remove the z-index and transform from .bank or it will be impossible because your elements will never belong to the same stacking context. As you can read in the previous link:
Each stacking context is self-contained: after the element's contents
are stacked, the whole element is considered in the stacking order of
the parent stacking context.
Related for more details: Why can't an element with a z-index value cover its child?
You can do this by adding z-index only to card class and placing the elements in absolute.
.bank {
width: 150px;
background: red;
height: 150px;
position: absolute;
top: 0;
left: 0;
}
.card {
width: 50px;
background: black;
height: 50px;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.button {
width: 100px;
background: blue;
height: 100px;
position: absolute;
top: 0;
left: 0;
}
<div class="bank">
<div class="card"></div>
</div>
<div class="button"></div>

span 100% height of parent button

I have the following markup
<button class="filter"><div class="radio"><div class="circle"></div></div> <span>Account Management</span></button>
and CSS
.filter {
font-size: 3vw;
text-align: left;
line-height: 1.6;
padding: 0px;
display: block;
height:auto;
overflow: hidden;
margin-bottom: 3px;
}
.filter span {
background: $leithyellow;
height: 100%;
overflow:auto;
display: block;
width: calc(100% - 60px);
float: left;
margin-left:10px;
padding-left:20px;
}
I cannot get the span to expand to 100% height of the button. Can this be done?
Heights apply only if the heights are defined properly for the ancestors. If you want the height to work, that's a tricky one. You can use one of my favourites, but you need to make sure it works in all the cases:
Give position: relative; to the parent.
Give position: absolute; to the element that needs full height and width.
Give the element, 0 values for all the sides.
Snippet
.parent {
position: relative;
width: 100px;
height: 50px;
background: red;
}
.parent .child {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: skyblue;
}
<div class="parent">
<span class="child"></span>
</div>
In the above snippet, it is noted that this can also work, if you give:
.parent {
position: relative;
width: 100px;
height: 50px;
background: red;
}
.parent .child {
position: absolute;
width: 100%;
height: 100%;
background: skyblue;
}
<div class="parent">
<span class="child"></span>
</div>
One good part about this approach is, you don't need to use the dangerous calc:
.parent {
position: relative;
width: 150px;
height: 50px;
background: red;
}
.parent .child {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 60px;
background: skyblue;
}
<div class="parent">
<span class="child"></span>
</div>
Note: On a related note, you can also have a look at this question and answer: Calc() alternative to fixed side bar with content?
Set display: flex to the parent
Set align-self: stretch for the child
This will stretch the height of the child div/button to fit the height of its parent without doing any trick.
By using position: absolute instead of flex-box, it won't be very nice eventually when you have more stuff added or re-arrange later on would be the nightmare.

Resources