Good afternoon,
I've made a very simple page demonstrating the different position types we can use in css for a new starter at our company, and quite embarrassingly this has exposed a gap in my own knowledge.
I have positioned all elements on the page but I've noticed that my relative positioned element will sit on top of my sticky element when the page is scrolled. It is almost like it has a z-index which is higher than my sticky element - I haven't set any z-index values though.
Is this the correct behavior given code I have provided? Apologies if this is really simple stuff, It has me sitting here scratching my head.
CodePen
body {
font-size: 20px;
font-family: Arial, Helvetica, sans-serif;
height: 3000px;
}
.relative {
width: 20%;
min-height: 200px;
background-color: dodgerblue;
color: white;
padding: 10px;
position: relative;
}
.sticky {
position: sticky;
background-color: green;
color: white;
padding: 10px;
width: 20%;
height: 200px;
top:0;
}
.fixed {
position: fixed;
padding: 10px;
background-color: aqua;
color: black;
height: 200px;
width: 20%;
right: 200px;
top: 300px;
}
.absolute {
position: absolute;
padding: 10px;
right: 0;
top: 0;
width: 20%;
height: 200px;
background-color: red;
color: white;
}
.static {
position: static;
width: 20%;
background-color: blueviolet;
padding: 10px;
color: white;
height: 200px;
}
<body>
<div class="sticky">
This is a sticky div
</div>
<div class="relative">
This is a relative div
</div>
<div class="absolute">
This is an absolute div
</div>
<div class="static">
This is a normal div
</div>
<div class="fixed">
This is a fixed div
</div>
</body>
Yes, this is normal behavior. Your relatively positioned element appears after your stickily positioned element in the source, so its natural stack level is higher and therefore it appears above the stickily positioned element. See section 9.9 of CSS2, or section 11 of css-position.
Stickily positioned elements obey the same stacking rules as relatively and absolutely positioned elements.
If two elements are in the same stacking context (have the same z-index value), then the browser will just look at the order that they are inserted in the dom: the last one would appear on top of the previous.
Here's more info on this topic: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index
When the z-index and position properties aren’t involved, the rules
are pretty simple: basically, the stacking order is the same as the
order of appearance in the HTML. (OK, it’s actually a little more
complicated than that, but as long as you’re not using negative
margins to overlap inline elements, you probably won’t encounter the
edge cases.)
When you introduce the position property into the mix, any positioned
elements (and their children) are displayed in front of any
non-positioned elements. (To say an element is “positioned” means that
it has a position value other than static, e.g., relative, absolute,
etc.)
https://philipwalton.com/articles/what-no-one-told-you-about-z-index/
Z-index only works on elements that have been position with absolute, relative, fixed. As your sticky element appears before your static element in the HTML, it will take precedence in the stacking order.
Related
I need to use this shape and inside that shows a text. But, I don't know why the text is not showing.
HTML:
<div id="thebag">
<h3> Shihab Mridha </h3>
</div>
CSS:
#thebag{
position: relative;
overflow: hidden;
}
#thebag::before{
content: '';
position: absolute;
top: 0;
left: 0;
height: 50px;
width: 30%;
background: red;
}
#thebag::after {
content: '';
position: absolute;
top: 0;
left: 30%;
width: 0;
height: 0;
border-bottom: 50px solid red;
border-right: 70px solid transparent;
}
https://jsfiddle.net/kn87syvb/1/
You need to add position: relative (or position: inherit, since it's the same as the parent) to your #thebag h3 class. Currently, your CSS styles are only affecting the parent of the h3—in order for the h3 to show with the text, you need to define CSS styling for it.
https://jsfiddle.net/kn87syvb/2/
By setting a position:absolute to the #thebag::before you "broke" the flow and your text is behind your div. You have to precise, than the h3 tag will be relative depending it's container.
So you have to add this :
#thebag h3 {
position:relative
}
To precise all h3 on your #thebag section will be affected. Be careful, if you change your kind of selector, It won t work anymore.
May be it will be better to use a custom class, like this https://jsfiddle.net/kn87syvb/5/
You need to use postion:relative property:
#thebag h3{
postion:relative;
}
Small explanation:
position: relative will layout an element relative to itself. In other words, the elements is laid out in normal flow, then it is removed from normal flow and offset by whatever values you have specified (top, right, bottom, left). It's important to note that because it's removed from flow, other elements around it will not shift with it (use negative margins instead if you want this behaviour).
However, you're most likely interested in position: absolute which will position an element relative to a container. By default, the container is the browser window, but if a parent element either has position: relative or position: absolute set on it, then it will act as the parent for positioning coordinates for its children.
please check this snippet:
https://jsfiddle.net/kn87syvb/4/
You can also re-structure your HTML and CSS as follows:
HTML
<span class="start">Shihab Mridha</span>
<span class="end"></span>
CSS
.end {
height:0;
width:0;
float: left;
display: block;
border:10px solid #0f92ba;
border-top-color:transparent;
border-right-color:transparent;
border-bottom-color:#0f92ba;
border-left-color:#0f92ba;
}
.start{
height: 20px;
width: 60px;
float: left;
background: #0f92ba;
display: block;
color:#FFFFFF;
}
Reference Link : https://solutionstationbd.wordpress.com/2011/12/21/trapezoids-shape-with-css/
I have a left panel with fixed position(it's always on the left side, nomatter how much you scroll) and also few elements in that left panel. On a certain event a mask appears(it goes over everything because position:fixed; z-index: 102).
My goal is when X event fires and the mask come up, to show up the holder element over the mask.
Here is a fiddle showing my problem: JSFIDDLE
Here is my HTML:
<div class="leftpanel">
<div class="just-random-elem" style="height: 30px;">just an element to move the holder abit down</div>
<div class="holder">asdasdas</div>
</div>
<div class="mask"></div>
<div style="height: 9999px;">Just to make sure both mask and leftpanel are with fixed positions.</div>
and here's the CSS:
.mask {
opacity: 0.85;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 101;
background-color: #000;
}
.leftpanel {
width: 250px;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background-color: red;
padding: 15px;
}
.holder {
width: 230px;
height: 90px;
background-color: #fff;
z-index: 99999; <<<<<<<<<< This is NOT working!
}
Your .holder element is no positioned, so z-index simply has no effect on it. You need to add a position value different from the default static – relative will do.
http://jsfiddle.net/DJA5F/4 works that way in every browser I tested – except Chrome. Can’t spontaneously say if Chrome is handling stacking contexts correct here and the others are not – or if it’s the other way around.
Works in Chrome as well if you put #mask into .leftpanel: http://jsfiddle.net/DJA5F/5 – might not be the nicest workaround, but since it’s postioned fixed, it does not actually matter, since the orientation for fixed is the viewport.
I know that bottom, top, left, and right with position: absolute sets that edge of the element to some distance away from that edge of the parent element. But how is the edge of the parent defined? Where is it in the box model? Does it include the border or the margin? The padding?
It's within the border, but ignores the padding.
Let's show it with an example. View on JSFiddle
HTML
<div>
<span>absolute</span>
regular
</div>
CSS
div {
position: relative;
top: 50px;
left: 50px;
background: #eee;
padding: 15px;
width: 100px;
height: 100px;
border: 5px solid #222;
}
span {
position: absolute;
top: 0;
left: 0;
}
Of course, an absolutely positioned element is positioned in relation to the first parent it comes across that is positioned with anything other than static. If the div in my example had no position set, the body of the fiddle would be used as that parent.
I have a problem with a float which overflows (JSFiddle here).
HTML
<div id="father">
<div id="son">
gruik
</div>
<div id="dog">
gruikgruik gruik gruik gruikg ruik gruik gruikgr uikgruik gruik gruik gruik
</div>
</div>
CSS
div { border: solid; }
#father { width: 300px; position: relative; }
#father:after { content: ""; display: block; clear: both; }
#son { width: 100px; float: left; border: solid red; }
#dog { float: left; border: solid blue; position: absolute; left: 105px; }
As you can see, #dog overflows from #father. I tried classical CSS techniques but they just do not work (neither the clearfix method, nor overflow:hidden; or overflow:auto;).
I think the problem appears because of the use of the position CSS properties but I need it.
position: absolute; is correctly positioning the #dog element relative to #father (because #father has position: relative;).
However it is only the #son element which is giving #father its height. Elements positioned absolutely are taken out of the flow and therefore if #dog increases in height, its parent container (#father) will not, and therefore #dog looks to be overflowing.
Why do you have to use position: absolute; on #dog?
Can you not just use float, and set its width? You are setting its parent and siblings widths anyway so you know what width it should be (if you specify the width of the borders too).
DEMO: http://jsfiddle.net/sgw4K/5/
EDIT/UPDATE: After discovering additional styling, thirtydot has recommended two sound fixes to the problem. See comment below or the following:
To fix that, you can remove float: left from #son and then pick one of
these two choices: margin-left: 52px or overflow: hidden; on the #son element.
So I have three div's
One parent and two child.
The parent is as follows:
#parent {
overflow:auto;
margin: 0 auto;
margin-top:37px;
min-height: 100%;
width:875px;
}
the two child divs are as follows
#child1 {
overflow:auto;
min-height:150px;
border-bottom:1px solid #bbb;
background-color:#eee;
opacity:0.4;
}
#child2 {
height:100%;
background-color:white;
}
The parent div extends 100% as I can see the borders of it till the end of the page but the child2 is not extending down to the end of the page like the parent div.
height doesn't behave the way you seem to be anticipating. When you specify height: 100% that percentage is calculated by looking up the DOM for the first parent of said element with a height specified that has absolute or relative positioning.
You can cheat when it comes to the body tag, so if you had something like this:
<body>
<div style="height: 100%">
</div>
</body>
Some browsers/versions will behave the way you expect by taking up the total height of the page. But it won't work when you go any deeper than that.
Here is the approach I use to strech a div to the bottom of the page, it involves absolute positioning (nice thing about this one is that it is pretty cross-browser compliant and doesn't require javascript to pull it off):
<div id="parent">
<div id="childNorm"></div>
<div id="childStrech"></div>
</div>
#parent
{
position: absolute;
width: 1000px;
bottom: 0;
top: 0;
margin: auto;
background-color: black;
}
#childNorm
{
position: absolute;
width: 1000px;
top: 0;
height: 50px;
background-color: blue;
color: white;
}
#childStrech
{
position: absolute;
width: 1000px;
top: 50px;
bottom: 0;
background-color: red;
color: white;
}
Here is a Jsfiddle for demo: http://jsfiddle.net/t7ZpX/
The trick:
When you specify absolute positioning and then put in bottom: 0; that causes the element to stretch to the bottom of the page; You just have to worry about positioning the elements as a trade off.
Yes, this is one of the annoying things in css. min-height is not considered a "height" for purposes of calculating height. See http://jsfiddle.net/3raLu/3/. You need to have height: 100% on the parent div to make the child full height. Or, if you can have it be absolutely positioned, then this works: http://jsfiddle.net/3raLu/6/.