Document stacking context root element: <body> or <html>? - html

Here's what I know:
In HTML, the document's root element is <html>
A document's root element creates a stacking context, hence <html> is the root element of the first stacking context created in any HTML document
From this, I'd expect any z-index: -1 element to be positioned behind <body> (though in front of <html>) in a document where no other stacking context comes into play.
The following example, however, demonstrates otherwise in all modern browsers: http://jsfiddle.net/39q2u/
I've dug a little deeper in that second example: http://jsfiddle.net/39q2u/1/
Adding a background-color to <html> somehow makes the rendering engine realize that the z-index: -1 element should indeed be displayed behind <body>, effectively making it invisible since <body> also has a background-color set.
Interestingly, I've given a try to several other CSS properties, an none of them seem to have the same effect.
(The element remains visible in IE 9.)
Removing the background-color from <body> makes the z-index: -1 element appear again, proving it was hidden behind <body>.
The issue I'm having with this is how to make sense of that behavior:
Is <body> subject to additional rules when it comes to stacking contexts?
Why is it needed to set a background-color on <html> for the rendering engine to behave correctly?
Or did I just misunderstand something, somewhere?

The default background-color of html is transparent. Thus, elements with a negative z-index are displayed, because you can see them "through" the html element. The link provided by #thirtydot points toward the right direction, although perhaps this link: http://www.w3.org/TR/css3-background/#background-color might be more on point.

I am not 100% sure but I believe the body tag always follows a z-index which is relative to other elements to make it easier when ordering multiple elements on the page.
If you apply an attribute to html, it suddenly becomes, and behaves like any other element, therefore putting it's child element, tag, into use as an element on the page also. Think of it as if you have toys you can play with, then toys you cannot reach. By assigning an attribute to the html, you are bringing the toys you could not reach into reaching distance. You are allowing the webpage to use the and subsequently the
That made sense in my head but I am stood from a bias stance so I hope that helped!

actually your expectation working as described except for the background property
take a look at this snippet it a prove that p element under body after positioned with negative integer :
html{
border: 20px solid green;
width: 250px
}
body {
padding:0;
margin:0;
width: 200px;
border: 20px solid orange;
overflow: hidden;
background:red;
}
p {
position: relative;
z-index: -1;
background: yellow;
}
<p>helllllllllllllllllllllllllllllllllllllllllllo</p>
so we can now exclude z-index from reasons
and It looks like a weird behavior on background-color property
I think it's better to read about it by following this links :
https://css-tricks.com/just-one-of-those-weird-things-about-css-background-on-body/
Giving background-color to body applying whole page. Why?

Related

is it possible to create a new stacking context WITHOUT the element being painted as if it's positioned?

what is the question?
Under the current spec of CSS, for any element, creating a new stacking context is equivalent to being painted as if it's positioned.
Various properties creating a new context like opacity, isolation and so on inevitably lead the browser to handle the element with the property as positioned.
For example, if you just add to an element only opacity less than 1 and no position, the browser will paint the element as positioned. This means an element with opacity less than 1 and no position is always over any non-positioned elements.
Any property creating a new stacking context like isolation are the same.
You can check this info from this discussion.
https://github.com/w3c/csswg-drafts/issues/2717
So does anyone know any "hack" for creating a new stacking context WITHOUT the element being painted as if it's positioned?
why am i asking it?
background
I'm now developing a personal browser extension which adds popups, rect and so on to the web page the user is opening, through DOM scripting.
I don't wanna change anything about the original DOM including style, because I want the basic view of the web page to be kept as the original.
All I can do is just add/insert some new DOMs without destroying the web page.
the main problem
In the development mentioned above, i wanna insert some elements with position: relative between two div elements: one is without any setting of position and the other is without any setting of position but with float setting.
Please run the below snippet. I wanna insert some positioned elements between them.
<!DOCTYPE html>
<html lang="en">
<body>
<div class="cover">float: left and no-position</div>
<div class="target">no-float and no-position</div>
</body>
</html>
<style>
.target {
color: white;
background-color: red;
height: 200px;
width: 200px;
}
.cover {
color: white;
background-color: blue;
height: 100px;
width: 180px;
float: left;
}
</style>
Of course, just inserting some elements with position: relative fails, because positioned elements are painted always over non-positioned elements.
Here, if i can create a new stacking context between them, the goal will be achieved.
However, again, under the current spec of CSS, for any element, creating a new stacking context is equivalent to being painted as if it's positioned. That means newly created stacking contexts are always over the floated elements...
So anyone has a solution?? Thank you for taking your precious time!

Why does opacity property carry over to an "irrelevant" element? [duplicate]

I'm coding a "popup window" in JavaScript and I've come across an interesting thing:
The navy square under the popup window is visible even though I would expect it to be hidden. The popup was added after the square, so it should be on the top.
CSS opacity property of the navy square is 0.3. From what I've tried, it seems that every number from the interval (0,1) would yield the same result. If I change it to 1, then it behaves as expected (i.e. the part of the square under the popup is hidden).
I've tried to set the z-index property to 10 for the square and 100 for the popup, but it doesn't change anything.
What am I missing? Why is part of square displayed?
Tested browsers:
Firefox 3.6.x
Chrome 4
This is not a bug and is actually how it's supposed to work. It's a bit confusing as the elaborate description of Stacking Contexts doesn't mention anything about it. However, the visual formatting module links to the color module where this particular gotcha can be found (emphasis mine):
Since an element with opacity less than 1 is composited from a single
offscreen image, content outside of it cannot be layered in z-order
between pieces of content inside of it. For the same reason,
implementations must create a new stacking context for any element
with opacity less than 1. If an element with opacity less than 1 is
not positioned, implementations must paint the layer it creates,
within its parent stacking context, at the same stacking order that
would be used if it were a positioned element with ‘z-index: 0’ and
‘opacity: 1’. If an element with opacity less than 1 is positioned,
the ‘z-index’ property applies as described in [CSS21], except that
‘auto’ is treated as ‘0’ since a new stacking context is always
created. See section 9.9 and Appendix E of [CSS21] for more
information on stacking contexts. The rules in this paragraph do not
apply to SVG elements, since SVG has its own rendering model ([SVG11],
Chapter 3).
It's not a problem of opacity being more important than z-index, rather than z-index being relative to their stacking context (see z-index in the CSS2 specification).
In other words, z-index are only significant within the context of a positioned ancestor (whether its relative, absolute or fixed). What you need to do to fix your problem is add a position: relative; to the element that contain both your popup and your navy square, and probably add it a z-index: 1; . Seeing your screenshot it will probably be a top element such as a wrapper div.
Workaround for two elements, like divs: add a 0.99 opacity to your top element, and the order of both is reestablished.
opacity: 0.99;
An alternative to using opacity, is to use a transparent colour (with an alpha value)
So, rather than using
{
background: gray;
opacity: 0.5;
}
You could try
{
background: rgba(128,128,128,0.5);
}
It isn't identical, but I was encountering the same issue you were having, and the above fixed it.
Example code might be needed to debug this problem.
You might put overflow: hidden and possibly position: relative in a DIV which surrounds all the editor objects to try to force the elements to only be drawn within that DIV, e.g:
<div style="overflow: hidden; position: relative">
(Editor object buttons go here)
</div>
As a last resort, you could also try a iframe in between the two elements to try to stop them seeping through.
You might try to set the popup window's DIV like this using !important so the style doesn't change on applying new style or class:
background-color: white !important;
z-index: 100 !important;
opacity: 1.0 !important;
Then, make new CSS class:
.PopupElement
{
z-index: inherited;
opacity: inherited;
}
And add class to all elements in the window, like this for example:
<input value="posx" class="some_class PopupElement"/>
My guess is that this would work, since there is no priority in applying CSS attributes... as far as I know. =)
I had the same issue. Using rgba instead of color/opacity solved my problem. Working with LESS (in the Bootstrap framework), the fade() function did the conversion for me.
Although #Guillaume Esquevin already gave a great answer, I will try to expand on it in case someone ignores what a stacking context is (like I did).
As you can read here, there is something called stacking context, which refers to a group of elements sharing a parent that move together in the stack. An example could be a div and all its children.
There are three ways to create a stacking context: in the root of the document (the html element), by positioning the parent element, and by changing the opacity of the parent to something lower than 1.
Then, if you have a div with opacity lower than 1 and you want some sibling element of this div to appear behind it (and its children), you can create a new stacking context on such sibling by setting its position to relative or by changing its opacity as well.

Offset page to prevent sticky header from covering auto-generated anchors

I'm using jekyll to generate my pages and as anyone knows that uses jekyll, the anchor tags on h-tags are automatically generated.
Solutions I am not looking for:
Add padding — my h-tags are using margins because I'm a normal person. Also, my sticky header is 50px tall which means that all my h-tags would need a miniumum of 55(ish)px padding. This causes there to be too much spacing.
Create your own anchor in a span tag — this defeats the point of the autogenerated tags and I'm trying to live a D.R.Y. lifestyle.
Summary: I need to offset the anchor's position without changing the location of the h-tag.
If this has already been answered, I apologize for creating a duplicate question. I could not find the answer to this that was not 'solved' with the previous mentioned 'solutions'.
You may want to use the :target pseudo selector, which matches when the hash in the URL and the id of an element are the same. Therefore, the style will only apply to the h-tag which has been navigated to rather than all of them.
For example, you can use :target::before to add a margin to the top of the selected tag:
:target::before {
content: "";
display: block;
margin-top: -75px;
height: 75px;
}
Here, this technique was used along with an animation which removes the margin after one second so that the margin no longer exists if/when the user scrolls up the page.
Adding this solved my problem.
html {
scroll-padding-top: 70px; /* height of sticky header */
}

iPhone/iPad background image on wrong element

I have an issue where, ocassionally, when I set a background image on an HTML element it displays a completely random image that is also set as a background image elsewhere on the page.
For example, I have a list item that has a background image "myimage-abc.jpg".
I also have a div with a background image of "myimage-123.jpg". Everything is as expected for most people however for some Apple users (of which my Managing Director is one) the image "myimage-123.jpg" shows up on the list item as well as the div.
Has anyone else had this issue before? Any ideas how to get around it?
Thanks
Use inspect element on the element with incorrect background image and see which CSS selectors are overriding the background image that you want to have.
Then report back with the CSS selectors responsible for styling the elements in here. Keep in mind that CSS selectors are very particular about the way in which you use them.
Until then here's something that could be causing your problem, without my knowing your current CSS state.
From an answer on another question:
I've dealt with this before and it's always a strange issue. So here are some thoughts and examples of CSS behavior.
In CSS we have a hierarchy decided both on how you select an element and on its position within your stylesheet. Take for example the following CSS selectors:
body .test-parent .test-child {
color: red;
}
body .test-parent .test-child {
color: blue;
}
The result in this case would return color: blue; as the final style as it is the last read declaration for that elements color value.
However if we declare the following:
body .test-parent-two .test-child-two {
color: red;
}
body .test-child-two {
color: blue;
}
Then the final value is color: red;. This caught me off guard and it took me a while to notice the pattern and fix.
The problem here lies in the selectors. A more in-depth selector (longer / includes more in-between children) will override any others as can be seen by this JSFiddle.
Hope that also helps!

CSS positioning woes

I am new to CSS and learning it side by side while making a site.
I am confused about how to position elements.I want to know whether I should use div to position elements or do I do it directly by either using tags and ids.If I use tag names and IDs I don't have to use div separately to position the elements. I can both style and position at the same time.
When to use div and when not to?
Actually, I am trying to build something like this:
HTML5 has made divs a bit outdated with the introduction of the header, footer, aside, section, article tags and so on. In HTML5, divs should only be used when the content cannot fit inside one of the newer, more fitting tags that I just listed. Check out this article for better clarification.
If I understand your question properly, it appears to me that you have a misunderstanding of some very basic concepts.
Basically, a div can be thought of as a Container, Panel or Element which hosts other elements. You can position a div, but chances are you're also going to want to position any other element, so here is some very basic code:
Positioning an element:
<!doctype html>
<html lang="en">
<head></head>
<body>
<div id="uniqueDiv">
<!-- You cannot use the same ID on any element more than once on a page. If you need multiple elements with the same "id", use class instead. -->
<img id="one" src="one.png" />
<img id="two" src="two.png" />
</div>
</body>
</html>
* { margin: 0; padding: 0; outline: 0; border: 0; outline: none; border: none; }
uniqueDiv img {
margin: 10px 0 0 0;
}
#one {
float: left;
}
#two {
float: right;
}
The is the basic premise behind positioning. I did not add an example for Padding, but you should not position elements using Padding. You should use margin instead. Also, the line that begins with * is called a CSS Reset and the goal of a reset stylesheet is to reduce browser inconsistencies in things like default line heights, margins etc.
Here's a brief explanation of what this code does:
The top piece of code is obviously HTML. It should be placed in its own .html file. The bottom piece, the CSS, should be placed in its own .css file.
So, we have 1 div and two images inside it. In this scenario, we want to have one image to the far left of the div and another to the far right. We also want to push both images down by about 10 pixels (positioning).
So, uniqueDiv img {} is used to position all images contained within the uniqueDiv down by 10 pixels from the top of its div. #one {} and #two are used to float the image to the left and the right.
My advice as per the excellent book "The Truth About HTML5 by Luke Stevens" switching to "Sections" "Header", "Footer", "Aside" etc can have accessibility problems as HTML5 is not recognized by all devices so to combat this you can make use of ARIA "Roles". You can still use Divs and assign "Roles" for your layouts, but adopting the HTML5 approach is what I would do.
Some good info is here;
Improving Web Accesibility
Aria Roles 101