@@ -314,22 +314,36 @@ _html2canvas.Parse = function (images, options) {
314314 } ;
315315 }
316316
317- function setZ ( zIndex , parentZ ) {
318- // TODO fix static elements overlapping relative/absolute elements under same stack, if they are defined after them
319- var newContext ;
320- if ( ! parentZ ) {
321- newContext = h2czContext ( 0 ) ;
322- return newContext ;
317+ function setZ ( element , stack , parentStack ) {
318+ var newContext ,
319+ position = stack . cssPosition ,
320+ zIndex = getCSS ( element , 'zIndex' ) ,
321+ opacity = getCSS ( element , 'opacity' ) , // can't use stack.opacity because it's blended
322+ isPositioned = position !== 'static' ,
323+ isFloated = getCSS ( element , 'cssFloat' ) !== 'none' ;
324+
325+ // https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
326+ // When a new stacking context should be created:
327+ // the root element (HTML),
328+ // positioned (absolutely or relatively) with a z-index value other than "auto",
329+ // elements with an opacity value less than 1. (See the specification for opacity),
330+ // on mobile WebKit and Chrome 22+, position: fixed always creates a new stacking context, even when z-index is "auto" (See this post)
331+
332+ // z-index only applies to positioned elements.
333+ // however, firefox may return the value set in CSS even if it's not positioned
334+ if ( ! isPositioned ) { zIndex = 0 ; }
335+ stack . zIndex = newContext = h2czContext ( zIndex ) ;
336+ newContext . isPositioned = isPositioned ;
337+ newContext . isFloated = isFloated ;
338+
339+ if ( ! parentStack || ( zIndex !== 'auto' && isPositioned ) ||
340+ ( opacity && Number ( opacity ) < 1 ) ) {
341+ newContext . ownStacking = true ;
323342 }
324343
325- if ( zIndex !== "auto" ) {
326- newContext = h2czContext ( zIndex ) ;
327- parentZ . children . push ( newContext ) ;
328- return newContext ;
329-
344+ if ( parentStack ) {
345+ parentStack . zIndex . children . push ( stack ) ;
330346 }
331-
332- return parentZ ;
333347 }
334348
335349 function renderImage ( ctx , element , image , bounds , borders ) {
@@ -953,21 +967,21 @@ _html2canvas.Parse = function (images, options) {
953967
954968 var ctx = h2cRenderContext ( ( ! parentStack ) ? documentWidth ( ) : bounds . width , ( ! parentStack ) ? documentHeight ( ) : bounds . height ) ,
955969 stack = {
970+ el : element , // very useful when debugging
956971 ctx : ctx ,
957- zIndex : setZ ( getCSS ( element , "zIndex" ) , ( parentStack ) ? parentStack . zIndex : null ) ,
958972 opacity : setOpacity ( ctx , element , parentStack ) ,
959973 cssPosition : getCSS ( element , "position" ) ,
960974 borders : getBorderData ( element ) ,
961975 clip : ( parentStack && parentStack . clip ) ? _html2canvas . Util . Extend ( { } , parentStack . clip ) : null
962976 } ;
963977
978+ setZ ( element , stack , parentStack ) ;
979+
964980 // TODO correct overflow for absolute content residing under a static position
965981 if ( options . useOverflow === true && / ( h i d d e n | s c r o l l | a u t o ) / . test ( getCSS ( element , "overflow" ) ) === true && / ( B O D Y ) / i. test ( element . nodeName ) === false ) {
966982 stack . clip = ( stack . clip ) ? clipBounds ( stack . clip , bounds ) : bounds ;
967983 }
968984
969- stack . zIndex . children . push ( stack ) ;
970-
971985 return stack ;
972986 }
973987
0 commit comments