Normal z-index order makes p element here to be higher than h1 element. In my situation both have some background and h1 is overlapping p a little as a visual effect. Both elements are positioned relatively. So as the overlapping happens, p hides some part of h1 element. Is there an elegant solution to give p element lower z-index than h1 element without having to swap them and making them absolutely positioned?
<h1>Title</h1>
<p>description</p>
Just add the z-index. It should work fine. Working example.
Sample CSS:
h1
{
position: relative;
top: 20px;
left: 20px;
color: blue;
z-index: 50;
}
p
{
position: relative;
top: 0px;
left: 0px;
color: red;
background-color: yellow;
}
Simple. Just add a relative position and z-index to the H1, and a negative top margin to the paragraph.
Example: http://dabblet.com/gist/3828786
You can use z-index on relative positioned items. You just need to define the position attribute. See here: https://developer.mozilla.org/en-US/docs/CSS/Understanding_z-index/Adding_z-index
Add the following in head section:
<style type="text/css">
h1
{
z-index:2;
}
p
{
z-index:2;
}
</style>
Related
Please see this very simple snippet to illustrate my question below:
#container {
position: relative;
padding: 20px;
border: 2px solid gray;
}
#back {
position: absolute;
top: 0;
bottom: 50%;
left: 0;
right: 0;
background-color: #bbb;
}
<div class="col-sm-12" id="container">
<div id="back"></div>
<h1>Some Text</h1>
</div>
The h1 tag is after the back element, in the HTML code.
As I don't change its position property, it must be static.
And, as far as I know, static elements are positioned according to the flow of the page.
So… Why is the absolute-positioned div is shown above its sibling h1?
I am expecting to see it behind the h1 since it comes first.
Note that I know how to correct this behaviour, I'm just asking why!
Snippet with correction:
#container {
position: relative;
padding: 20px;
border: 2px solid gray;
}
#back {
position: absolute;
top: 0;
bottom: 50%;
left: 0;
right: 0;
background-color: #bbb;
}
/* Adding the below corrects this behaviour */
h1 {
position: relative;
}
<div class="col-sm-12" id="container">
<div id="back"></div>
<h1>Some Text</h1>
</div>
… And why using position: relative on the h1 corrects this behaviour?
This is how the painting order works. As described here you have the following order:
For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block
equivalent:
In this step you will print the background and border of the h1 element
Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
In this complex step you will print the content of the h1 element
All positioned, opacity or transform descendants, in tree order that fall into the following categories:
All positioned descendants with 'z-index: auto'
And in this step you will print the positioned element #back; thus it will be on the top of h1 even if in the DOM it's before.
In other words, we first consider the in-flow elements then the postioned ones. Of course, changing z-index and/or other properties will affect the order because more steps can be consider.
For example adding a negative z-index to #back will trigger this rule:
Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then
tree order.
This will make the #back to be behind since h1 is printed later in the step (4) and (7).
Adding position:relative (or absolute or fixed) to h1 will make it a positioned element so like #back it will trigger the (8) and in this case the tree order will decide.
You may also notice that both background and content are printed in 2 different steps and this may also lead to some non intuitive painting behavior.
Try following. Add style for h1 as follows
#container {
position: relative;
padding: 20px;
border: 2px solid gray;
}
#back {
position: absolute;
top: 0;
bottom: 50%;
left: 0;
right: 0;
background-color: #bbb;
}
#container h1 {
position : relative;
z-index: 1;
}
<div class="col-sm-12" id="container">
<div id="back"></div>
<h1>Some Text</h1>
</div>
static elements do not have a z-index, however, the others default to 0 that is why it stays at the bottom most layer of html and the non-static element covers it. If you wish to show them above, set the position of static elements to relative and give any positive z-index value.
The top, right, bottom, left, and z-index properties have no effect for position: static which is the default value for elements, in your case which h1 tag is. When position is set to relative it creates a new stacking context when the value of z-index is other than auto.
For more read on stacking context:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
I am trying to have a div at the top of my page that fits with no space against the top and sides.
All the example I have seen on how to do this put the div position to absolute.
But when I do this, the following img sibling moves to the top of the page with the previous div.
So I have two questions. Why does the following sibling move? Also, how can I have a div fit with 0 space against the top, without having position:absolute
div {
position: absolute;
top: 0px;
left: 0px;
background: #888888;
width: 100%;
height: 100px;
}
<body bgcolor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">
</body>
</html>
You don't need position: absolute to align things to top just use margin: 0 on the body, h1 Like:
body, h1 {
margin: 0;
}
Have a look at the snippet below:
body, h1 {
margin: 0;
}
div {
background: #888888;
width: 100%;
height: 100px;
}
<!DOCTYPE html>
<html>
<body bgcolor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="http://placehold.it/304x228" alt="Mountain View" style="width:304px;height:228px;">
</body>
Hope this helps!
When you give an element position: absolute, you remove it from the normal flow of the document. This means that it no longer takes up any space in the layout. As a result, surrounding elements don't know it exists and take over the previously used space.
But you don't need absolute positioning in this case. The reason for the gaps are default margins on elements set by the browser. Just override those defaults with your own settings.
body, h1 {
margin: 0;
}
div {
height: 100px;
background: #888888;
}
<body bgcolor="#000000"bgcolsor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">
</body>
More information:
Normal flow ~ MDN
Absolute positioning ~ MDN
Why does the following sibling move?
It moves to the top because the first div is position: absolute, that's what expected when we apply this property / value. This div is also relative to the parent / body and the whole document (because no position: relative was specified anywhere else). When you apply position: absolute you remove that element from the normal document flow. It kind of flies over the document.
When you have this option applied to an element nested to something using position: relative, you'll see that the child will obey the parent's top, left, right and bottom.
Also, how can I have a div fit with 0 space against the top, without having position:absolute
This way:
body {
margin: 0;
}
With:
h1 {
margin-top: 0;
}
Or:
div {
overflow: hidden;
}
Without position: absolute; top: 0px; left: 0px; width: 100%; on the div. div's default params will take over what's needed.
The margin-top: 0 or overflow: hidden must be there just to get rid of the top h1's default margin, because when there's a margin in a case like that, the div background won't follow the whole div flow. Using overflow: hidden the way I've shown you is a technique of "clearing" things, like clearfix and others. You can read more about them here.
Also, Michael_B links about normal flow and absolute positioning are very relevant and a must read.
I have this code
#mtitle {
display: inline-block;
margin: 0;
background-color: #000000;
z-index: 999;
}
#tsub {
display: inline-block;
margin-left: 0;
left: 0;
position: absolute;
font-size: 85px;
z-index: 0;
}
<header>
<h1 id="mtitle">Tepid Beans</h1>
<div id="tsub"><span>- Games</span>
</div>
</header>
#tsub is appearing on top of #mtitle, and I do not know why.
z-index works on positioned elements, but with CSS3 elements which are flex items or grid items can use z-index when elements are static
From MDN
The z-index property specifies the z-order of an element and its
descendants. When elements overlap, z-order determines which one
covers the other. An element with a larger z-index generally covers an
element with a lower one.
For a positioned box, the z-index property specifies:
The stack level of the box in the current stacking context.
Whether the box establishes a local stacking context.
Applies to positioned elements
Set position:relative to parent header and position:absolute to #mtitle and change z-index value
body {
margin: 0
}
header {
position: relative
}
#mtitle {
display: inline-block;
background-color: #000000;
position: absolute;
margin:0;
z-index: 0;
color: #fff
}
#tsub {
display: inline-block;
left: 0;
position: absolute;
font-size: 85px;
z-index: -1;
background: red
}
<header>
<h1 id="mtitle">Tepid Beans</h1>
<div id="tsub">- Games</div>
</header>
Although other answers posted here solve the problem, they are not entirely correct.
The following statements are false:
z-index only works on positioned elements.
z-index only works on elements that are positioned.
z-index only works on elements which are not position:static ie the default position.
In many cases an element must be positioned for z-index to work. But this is not true for all cases.
Elements that are flex items or grid items can create stacking contexts with z-index, even when position is static (see demo).
In terms of this specific question, the reason #tsub is appearing on top of #mtitle is because:
div#tsub comes after h1#mtitle in the HTML, AND
the z-index property applied to #mtitle is being ignored since #mtitle is not positioned, nor is it a flex or grid item.
Here are two possible solutions:
change z-index: 0 on #tsub to z-index: -1, OR
add position: relative to #mtitle
#mtitle {
display: inline-block;
margin: 0;
background-color: aqua; /* changed for illustration purposes */
z-index: 999;
}
#tsub {
display: inline-block;
margin-left: 0;
left: 0;
position: absolute;
font-size: 85px;
z-index: -1; /* adjustment here */
}
<header>
<h1 id="mtitle">Tepid Beans</h1>
<div id="tsub"><span>- Games</span>
</div>
</header>
z-index only works on elements that are positioned. So if you add position: relative; to #mtitle the z-indexing will work.
concerning the last part of your question,
tsub is appearing on top of #mtitle, and I do not know why.
elements with position: absolute are "taken out" of the regular flow of elements, they don't take up any space in their parent elements (which need a position setting other than static for that to work), they are only anchored to them (= will move with them). But that way they can overlap other elements.
Among several absolutely positioned elements, the z-index will determine which one is on top of another one..
I have DIV container with relative position, and the child with absolute position.
here is my code source:
JSFIDDLE
HTML:
<div class="wrapper">
<h1>Hello</h1>
</div>
CSS
.wrapper {
background: red;
width: 100px;
height: 100px;
position: relative;
}
.wrapper h1 {
color: #333;
position: absolute;
top: 60px;
}
when I put in top 60px, the child element jump to the bottom , normally the container has a relative position so the child element should be under the container not over the container.
Please, someone can explain me why this happen ?
I hope I explained, well my question.
When you have an element with position: absolute that element is placed relatively to its closest positioned parent. A positioned element is any element with position different from static, be it relative, absolute or fixed.
In your case you have a .wrapper with position: relative and h1 inside it with position: absolute, that is why the latter is positioned 60 pixels from the top of its parent.
If you insist of the child element being below the parent, add z-index: -1 to it - http://jsfiddle.net/jt92sedr/4/
This property applies only to positioned elements.
You can check: http://www.barelyfitz.com/screencast/html-training/css/positioning/
The CSS is actually doing what you think (sort of), but there is also (in Firefox, at least) a 21 pixel top margin which pushes the "text" down a bit farther.
Add a rule to remove the top margin:
.wrapper h1 {
color: #333;
position: absolute;
margin-top: 0; /* added this */
top: 60px;
}
Try adding "margin:0; to the h1 element:
.wrapper h1 {
color: #333;
position: absolute;
top: 60px;
margin:0;
display:block;}
Its the other way around, Relative always means relative to the parent. if you want to the child to be set in relation to parent, then make it relative.
the relative in your case on parent does not mean anything.
Are you wondering why 60px from top of the div looks like 80px or 90 px? If this is your question, answer is easy. Browsers add some margin to h1, div and body elements. Simply clear that efect:
body, div, h1 {
margin: 0;
padding: 0;
}
http://jsfiddle.net/14sLb8jg/
Modern browsers, like Chrome and Firefox, are putting a 0.67em margin on top and bottom of h1 tags.
In your case declaring a margin 0 for .wrapper h1 will solve your problem.
Your code should be:
.wrapper {
background: red;
width: 100px;
height: 100px;
position: relative;
}
.wrapper h1 {
color: #333;
position: absolute;
top: 60px;
margin: 0;
}
If you are in doubt, use your browser's inspection / developer tools to find out what default stylings the browser is giving into any given element so you know which one you need to override.
Jsfiddle Example
View on Jsfiddle
I need to set a margin to the top of an element. The text must be within the element and have a top margin of N pixels.
Here is what I want to achieve:
Fiddle: http://jsfiddle.net/GRQNh/
CSS:
body {
height: 960px;
}
.breadcrumbs {
position: relative;
background-color: #eee;
height: 10%;
}
.name {
color: #000;
margin-top: 50px;
}
Thanks.
DEMO or you may be try with padding-top instead margin-top as follows
.name {
display:block;
color: #000;
padding-top: 50px;
}
Since .breadcrumbs has position: relative, set position: absolute; to .name.
JSFiddle
You need to add display: inline-block; to get the margin to work.
For instance,
.name {
color: #000;
margin-top: 50px;
display: inline-block;
}
Hope this helps.
For it to work you will need to make the element behave like a block element. A block element can have, for instance, margins or paddings.
However, you will want to keep it from being displayed like an actual block element, so you will want to keep its visual displacement the same (that is, inline).
Luckily, there is a css value for display which does exactly what you need:
display: inline-block;
Add this to the span (which is inilne by default) and it will behave like a block element while it will still look like an inline element.
You can also give up on margins at all and use padding-top: 50px.
in this case, you must specify the parent ELEMENT position relative and absolute position subsidiary and specify top: 0;
the <span> is an inline element. That means you cant apply margin or padding to it.
For the solution to your problem you have -at least- two options.
1.Change the container of your text to a block element, like <div>
so:
<span class="name">Name</span>
will become
<div class="name">Name</div>
2.Change the behavior of your span by making it a block or inline-block element with this css:
.name {
display:inline-block
/* rest of your css */
These two articles will give you a good idea of what is inline and block
http://www.impressivewebs.com/difference-block-inline-css/
http://css-tricks.com/almanac/properties/d/display/