Forum Moderators: not2easy
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Pseudo Element Stacking</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<style type="text/css" media="screen">
/* image being used: http://www.google.co.uk/images/logos/ps_logo2.png - 364px x 126px */
#logo {
position: relative;
z-index: 1;
border: 1px solid #00f;
height: 126px;
width: 364px;
text-align: center;
font: 40px/106px Georgia, "trebuchet ms", sans-serif;
padding: 10px;
color: #00f;
background: #ccc; /* to show background of background :o! */
}
#logo:after {
content: "";
background: transparent url(http://www.google.co.uk/images/logos/ps_logo2.png) no-repeat 0 0;
width: 364px;
height: 126px;
position: absolute;
z-index: 1000;
top: 10px;
left: 10px;
}
img {float: left; margin: 20px 20px 0 0;}
#info {overflow: hidden;}
</style>
</head>
<body>
<h1 id="logo">Google</h1>
<h2>IE8 Stacking Context?</h2>
<img src="http://www.google.co.uk/images/logos/ps_logo2.png" alt="">
<div id="info">
<p>The bordered "google" header above contains the image also shown on the left of this paragraph</p>
<p>The header above should show no "plain text" on top of it - but should show plain text if images are off, and also still show text if CSS is off </p>
<p>it does not work in IE7 or below without a script, I'm thinking it should work in IE8, but it doesn't! Any insight gratefully received..
<p>also looking for the feedback on how it works in IE9, Safari, Opera versions etc.</p>
<p>Tested working in FF, Chrome, Opera 10</p>
</div>
</body>
</html>
<h1 id="logo"><span>Google</span></h1>
with
span {
position:absolute;
top:-10px; /* top and left set to track location */
left:-10px;
z-index:-1; /* note the negative, also note that to make it easy I set #logo = z-index:1 #logo:after = z-index:2 */
background-color:aqua;
}
I've tried a few ideas tweaking the code but nothing seems to work for me either.Sounds helpful - I'd like to explore this further, but as stated, have limited time - would you mind very much sharing what you tried but didn't work: It will save trying the same things, and as discussions in other threads show, will definitely prompt deeper thought and discussion ;)
<h1 id="logo">Google<span></span></h1> and then applying the exact same CSS to #logo span {} as to #logo :after {} which works as expected in IE7 as well as 8, so it seems that IE8 is not quite getting the pseudo element right, in truth this would hardly be noticeable if using the technique for multiple backgrounds as there wouldn't be text there anyway, but still ;) [edited by: alt131 at 10:59 pm (utc) on Dec 24, 2011]
:before and :after pseudo elements could give a lot of scope for getting multiple images in there - think those designs that always wanted an image fixed to the bottom right corner or fancy borders around headings.. #logo {
position: relative;
z-index: 1;
border: 1px solid #00f;
height: 126px;
width: 364px;
text-align: center;
font: 40px/106px Georgia, "trebuchet ms", sans-serif;
padding: 10px;
color: #00f;
}
#logo:after {
content: url(http://www.google.co.uk/images/logos/ps_logo2.png);
background: #008 url(http://example.com/anotherimage.jpg) no-repeat top right;
position: absolute;
z-index: 1000;
top: 0px;
left: 0px;
width: 364px;
height: 126px;
padding: 10px;
}
/* general */
img {float: left; margin: 20px 20px 0 0;}
#info {overflow: hidden;}
what do you think now?It works as per the versions tested above - yay ;) And I agree, lots of opportunity to get creative. Oh what fun!
ignoring the :before/:after (and earlier FF) support for the minute, I *think* but am not sure that IE8 is wrong with it's stacking context hence I wanted to see if it works as described in IE9 yet.I'm with those who believe ie is wrong, although haven't fully explored ie8. I said it much better in this thread - Legacy IE and z-index:-1 vs z-index:0 [webmasterworld.com]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>My Title</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<style type="text/css">
/*Note that it is only necessary to declare z-index and positioning on the "pseudo-"ancestor. Also works for relative positioned ancestors (some solutions didn't), and you can use an image for content as well */
h1 {
position:absolute;
z-index:1;
width: 364px;
height: 126px;
border:1px solid red;
}
h1:after {
display:inline-block;
background: blue url(http://www.google.co.uk/images/logos/ps_logo2.png);
border:1px solid red;
content: " ";
margin-top:-20px;
width: 364px;
height: 126px;
}
</style>
<h1>My text</h1>
</body>
</html>
But am now wondering what the question was. There's a difference between "why doesn't this work" , and "how can [this] be achieved" - although avoiding Appendix E earns extra points wink
although hasLayout was "reportedly" removed in IE8 ...Humph. I believe I successfully triggered it several times before remembering it doesn't exist :) (In fairness there are so many variables it could be something else.)
IE had an issue with (explicit) auto setting a new context so I tried with/without it and various negativesAs above, apparently fixed in ie8, but now applied to z-index:0. At this stage of my testing I've put it in the same category as the (supposedly) fixed haslayout. As we know, negatives didn't resolve the issue of the associated elements content showing through. There are several possible reasons/"culprits", and in pursuing that I have a test that causes winSafari and ff to slide the :after below 4 parents to draw it just above the root. (Ie just slides it below 3.) Fun
although is a work-around for inline-block still required?
inline-block.. and not "block" or "floats which become blocks" - follows is the reason I think it's so - that is IE's natural workaround Within each stacking context, the following layers are painted in back-to-front order.
1. the background and borders of the element forming the stacking context.
2. the child stacking contexts with negative stack levels (most negative first).
3. the in-flow, non-inline-level, non-positioned descendants.
4. the floating descendants.
5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
6. the child stacking contexts with stack level 0, and the positioned descendants with 'z-index: auto'.
7. the child stacking contexts with positive stack levels (least positive first).
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>My Title</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<style type="text/css">
h1 {
width: 364px;
height: 126px;
padding: 10px;
background: #fee;
font: 40px/126px sans-serif;
border:1px solid red;
margin: 0;
}
h1:after {
display: inline-block; /* doesn't work if this is block, floated (block by default) or positioned! */
width: 364px;
height: 126px;
border:1px solid blue;
content:"";
background: blue url(http://www.google.co.uk/images/logos/ps_logo2.png) no-repeat 0 0;
position: relative;
left: 0;
top: -126px; /* need an line-height the equivalent to the box height to calculate */
}
p {margin: 10px 0; background: #dad;}
</style>
</head>
<body>
<h1>My text</h1>
<p>but where does the paragraph after go?</p>
</body>
</html>
Given the purpose of pseudo elements, I can't immediately think of a best practise application using a background-image but no content an :after
body {padding: 10px 20px;}
p {margin: 1em 0;}
.example {
width: 720px;
padding: 170px 20px 11px 20px;
background: #fcf url(body-middle.gif) repeat-y 0 0;
position: relative;
}
.example:before {
background: url(body-top.gif) no-repeat 0 0;
content: url(banner_fresco.jpg);
text-align: center;
padding-top: 11px;
height: 151px;
width: 760px;
position: absolute;
top: 0;
left: 0;
}
.example:after {
background: url(body-bottom.gif) repeat-y 100% 0;
content: "";
padding: 0;
height: 12px;
width: 760px;
position: absolute;
bottom: 0;
left: 0;
}
Not sure what the expected display is (only have access to IE9 and Chrome on my test system), but it looks the same to me in IE9 as it does in Chrome.
[edited by: alt131 at 11:06 pm (utc) on Dec 24, 2011]
Q: What were you trying that broke it, were you trying the floats and stuff?..... errrr... invalid code will do it ;)
I discovered that it would only work with inline-block..... I should have said that out loud. Sorr-eeee!
...feeding JS <spans> ... could we use jquery to target ... was actually thinking we could use this technique for multiple backgroundsI'm pretending this does not open the door to a gazillion server hits to download js to force recognition of pseudo's that downloads gigs of background-images to make things nice for visual users.
/* birdbrains fancy border - css could be further simplified as all pseudo's are absolute and have same dimensions */
div.birdbrain {
/* position relative to control the pseudo's */
/* it is possible to leave position off the div, and instead set position, display and z-index on the pseudo, but that requires more code.*/
position:relative;
border:4px solid #ddd;
padding:20px;
width:240px;
height:300px;
}
div.birdbrain:before, div.birdbrain:after {
/*no display required because absolute pseudo takes dimensions */
position:absolute;
/*it is necessary to position the pseudo because it respects padding on the associated element*/
top:0;
width:20px;
height:20px;
content:"";
border-top:4px solid #000;
}
div.birdbrain:before {
left:0;
border-left:4px solid #000;
}
div.birdbrain:after {
right:0;
border-right:4px solid #000;
}
.birdbrain p {
position:relative;
padding:20px;
margin:10px;
background-color:#eee;
top:-10px;
left:-10px;
width:200px;
height:260px;
}
.birdbrain p:before, .birdbrain p:after {
position:absolute;
content:"";
width:20px;
height:20px;
bottom:-20px;
border-bottom:4px solid black;
}
.birdbrain p:before {
border-left:4px solid black;
left:-20px;
}
<div class="birdbrain"><p>Birdbrains amazing fancy borders!</p></div>
so using this page: CSS3.info example [css3.info] and the images and HTML code from it..All respect to the css3.info team, but this seems a good example of the worst to come. It really requires a single header image, and I'd like a real (styled) uri that was clickable - it's wasted seo and I tried to click before realising it wasn't a link. (This also put me in mind of the "popular" opaque strips, but I haven't tested opacity yet). This took a couple of minutes - it isn't pixel-perfect, needs refining, but reduces your code even more.
div#css3_info {
width:720px;
height:200px;
border:3px double #C6C6C4;
padding:6px;
}
div#css3_info:before {
width:720px;
height:200px;
/* url modd'ed to save css3 hits */
background: #F1EFED url(break image link- [css3.info...] -9px 0 no-repeat;
content:" ";
position:absolute;
}
div#css3_info ul {
display:block;
position:relative;
top:125px;
padding:0;
}
div#css3_info ul li, div#css3_info ul li a {
display:inline-block;
padding: 0 1px;
}
div#css3_info h1 {
position:relative;
top:105px;
}
<div id="css3_info">
<ul>
<li><a href="#">My breadcrumbs</a> \</li>
<li><a href="#">My breadcrumbs</a> \</li>
</ul>
<h1>My Heading</h1>
<div>
h1#cross-browser_border_slants {
position:relative;
/* for control give an explicit line-height or height - hat-tip to suzy*/
line-height:40px;
/* Create a space for the pseudo */
/* Padding applies to pseudo's so position the text away from the pseudo's by giving the pseudo's a negative margin or left the same length as the padding. It is also possible to set a border on the associated element, then negatively position the pseudo on top of the border */
padding-left:50px;
}
h1#cross-browser_border_slants:before {
position:absolute;
content:"";
/* Remove the effect of padding on the pseudo */
left:0;
border-width: 0 20px 20px;
border-style:solid;
border-color:transparent;
border-bottom-color:navy;
}
h1#cross-browser_border_slants:after {
position:absolute;
/* Remove the effect of padding on the pseudo, then push it down below the :before = the pseudo border-width */
left:0;
top:20px;
content:"";
border-width: 20px 20px 0 20px;
border-style:solid;
border-color:transparent;
border-top-color:red;
}
<h1 id="cross-browser_border_slants">Cross browser border slants</h1>
div#polaroid {
position:relative;
left:100px;
width:150px;
height:200px;
/* Outline is tempting, but it has too many varying issues */
border:1px solid #aaa;
padding:10px;
text-align:center;
/* ie is too troublesome for a transform, but gets a zoom on hover */
-webkit-transform: rotate(-5deg);
-moz-transform: rotate(-5deg);
-o-transform:rotate(-5deg);
}
div#polaroid:hover {
zoom:1.1;
-webkit-transform: rotate(0deg) scale(1.25);
-moz-transform: rotate(0deg) scale(1.25);
-o-transform:rotate(0deg) scale(1.25);
/* un-comment the filter in to see the effect of a transform when a replaced element has a z-index */
/*-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476,sizingMethod='auto expand')";*/
}
div#polaroid img {
/* replaced content creates special issues, position and z-index so it displays below the pseudo (display:inline-block does not work in this case). This could be resolved by setting the image as a background-image, but it is actual content that really belongs in the html */
position:relative;
z-index:-1;
display:block;
margin-bottom:0.6em;
/* padding and background for visual effect because the image has a white background */
background-color: #eee;
padding:1px;
}
div#polaroid:before {
position:absolute;
left:-4px;
top:-4px;
content:"";
border-width: 20px 10px 10px 20px;
border-style:solid;
border-color:#eee transparent transparent #eee;
}
div#polaroid:after {
position:absolute;
right:-4px;
top:-4px;
content:"";
border-width: 20px 20px 10px 10px;
border-style:solid;
border-color:#eee #eee transparent transparent;
}
<div id="polaroid">
<img src="http://www.google.co.uk/images/logos/ps_logo2.png" width="150" height="150" alt="My image" >
My caption
</div>
h1#tanfa {
font-family:"times new roamn", serif;
color:#AA0000;
width:200px;
margin:0 auto;
position:relative;
}
h1#tanfa:before {
/* relative makes the default position relative to the header text -also why this is the before rather than the canopy, which is visually firt */
position:relative;
display:inline-block; /* takes dimensions without disturbing default location */
padding-right:10px;
height:16px;
width:13px;
content: "";
background: url(h2bgr.gif) no-repeat;
}
h1#tanfa:after {
/* absolute makes it easy to dimension this larger than associated element and then position outside the heading*/
position:absolute;
left:-200px;
top:-80px;
content: "";
width:396px;
height:126px;
background-image: url(css-canopy1.gif);
}
<h1 id="tanfa">CSS - index</h1>
[edited by: tedster at 2:30 pm (utc) on Dec 29, 2010]
[edit reason] fixed the link [/edit]
Layered presentation - that explains a simple example, but wouldn't a positioned element in a nest with all positive z-index's be painted per 8 - regardless of display? ... I'm sure something else is going on.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Pseudo Element Stacking</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<style type="text/css" media="screen">
#logo, #logo2 {
position: relative; /* to make containing block */
top: 0;
left: 0;
border: 1px solid #00f;
height: 180px;
width: 500px;
text-align: center;
font: 40px/2 Georgia, "trebuchet ms", sans-serif;
padding: 10px;
color: #00f;
background: #ccc; /* to show background of background :o! */
}
#logo:before, #logo:after,
.b, .a {
font: 20px/1.5 verdana;
width: 280px;
height: 100px;
position: absolute;
border-width: 3px;
border-style: solid;
text-align: center;
color: #fff;
}
#logo:before, .b {
content: "before text";
background: #f00;
border-color: #0f0;
top: 30px;
left: -10px;
}
#logo:after, .a {
content: "after text";
background: #080;
border-color: #0c0;
top: 50px;
right: -10px;
}
/*
#logo:after {
position: relative;
display: inline-block;
top: -120px;
right: -125px;
}
*/
</style>
</head>
<body>
<h1 id="logo">Anonymous text Anonymous Text</h1>
<p>Some following text</p>
<hr>
<h1 id="logo2"><span class="b">before text</span> Anonymous text Anonymous Text <span class="a">after text</span></h1>
<p>Some following text</p>
</body>
</html>
Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
8. All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
:before text under the 'anonymous' text? That would at least show some sign that there was an attempt at a tree order and perhaps something else going on? then we could say it's painting all the backgrounds then all the text in the right order (even though that would still not seem right) .. it's quite clear, to me anyway at the top of that "E" page that the descriptions refer to this: Element
In this description, "element" refers to actual elements, pseudo-elements, and anonymous boxes. Pseudo-elements and anonymous boxes are treated as descendants in the appropriate places. For example, an outside list marker comes before an adjoining ':before' box in the line box, which comes before the content of the box, and so forth.
"per 8" is that 8 from appendix "E" you're referring too?,Too long after bed-time – should be "per 7" - a reference to your list from section 9.9. "8" from Appendix E isn't relevant - no wonder you were confused. But this highlights the ambiguity and incompleteness of the stacking model (whether the 7 point list from section 9.9, or the 10 points in "E"). I initially read it as a hierarchy, but later "points" don't always seem to "over-ride" the earlier ones. As you refer, one issue is the language (exacerbated by me using it past bed-time.) My comment that stack order and painting order may not be the same was a poorly put reference to a cluster of thoughts:
This case is actually a simple one, it can be demonstrating without using z-index or creating stacking contexts at all…I take the opposite view –the recs make this complex by not dealing with all the issues, and the egs do create new stack contexts, plus use properties that trigger known issues. Or perhaps browsers are as confused as we, or just wrong, so the egs don’t work per the recs because they are just a “best guess” ;)
"per 8" is that 8 from appendix "E" you're referring too?,
Too long after bed-time – should be "per 7" - a reference to your list from section 9.9. "8" from Appendix E isn't relevant - no wonder you were confused. But this highlights the ambiguity and incompleteness of the stacking model (whether the 7 point list from section 9.9, or the 10 points in "E"). I initially read it as a hierarchy, but later "points" don't always seem to "over-ride" the earlier ones. As you refer, one issue is the language (exacerbated by me using it past bed-time.) My comment that stack order and painting order may not be the same was a poorly put reference to a cluster of thoughts:
[edited by: alt131 at 11:16 pm (utc) on Dec 24, 2011]
Within each stacking context, the following layers are painted in back-to-front order.
1.the background and borders of the element forming the stacking context.
2.the child stacking contexts with negative stack levels (most negative first).
3.the in-flow, non-inline-level, non-positioned descendants.
4.the floating descendants.
5.the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
6.the child stacking contexts with stack level 0, and the positioned descendants with 'z-index: auto'.
7.the child stacking contexts with positive stack levels (least positive first).
Positioned elements with 'z-index: auto' (in layer 6), floats (layer 4), inline blocks (layer 5), and inline tables (layer 5), are painted as if those elements generated new stacking contexts, except that their positioned descendants and any child stacking contexts take part in the current stacking context.
This painting order is applied recursively to each stacking context. This description of stacking context painting order constitutes an overview of the detailed normative definition in Appendix E.