I would like to set the mix blend mode of an anchor inside of a position:fixed
element but it is not applied.
If I apply the mix blend mode to the parent element it works or if I set the parent element to position:absolute
it also works but neither of these are what I'm wanting to achieve.
Codepen with the three examples, I'd like #nav to look like #nav2 and #nav3 with the existing html.
http://codepen.io/wesdeboer/pen/QjawYv
HTML
<body>
<div id="nav">
<a href="">fixed</a>
</div>
<div id="nav2">
<a href="">absolute</a>
</div>
<div id="nav3">
<a href="">parent</a>
</div>
</body>
CSS
body { background: url(http://lorempixel.com/400/200)}
#nav {
position: fixed;
top:0;
left: 0;
}
#nav2 {
position: absolute;
top:0;
left: 100px;
}
#nav3 {
position: fixed;
top: 0;
left: 250px;
mix-blend-mode: difference;
}
a {
color: white;
font-weight: bold;
font-size: 32px;
mix-blend-mode: difference;
}
Tested in Chrome 45
The reason why it doesn't work is that the white sections don't really have a white background. They have no background-color set, so they fall back to the default value of transparent . Visually this is manifested as a white color, but to the compositor it will still be transparent .
The mix-blend-mode CSS property sets how an element's content should blend with the content of the element's parent and the element's background.
difference : this subtracts the darker of the two colors from the lightest color. exclusion : similar to difference but with lower contrast. hue : creates a color with the hue of the content combined with the saturation and luminosity of the background.
The reason position: fixed;
on a parent element prevents mix-blend-mode
from behaving as you expect is that position: fixed;
creates a new stacking context, isolating the child element from the rest of the document.
I verified that this is indeed the issue by forking your example and creating a new nav item which creates a new stacking context in a different way: by positioning it absolutely and setting z-index
. This new stacking context prevents the child element from blending with the background image outside the stacking context, just as we observed with the position: fixed;
element.
position: fixed;
and position: absolute; z-index: 3;
are just two of many ways to create a new stacking context, all of which should create this issue:
- Element with a
position
valueabsolute
orrelative
andz-index
value other thanauto
.- Element with a
position
valuefixed
orsticky
(sticky for all mobile browsers, but not older desktop).- Element that is a child of a flex (
flexbox
) container, withz-index
value other thanauto
.- Element that is a child of a grid (
grid
) container, withz-index
value other thanauto
.- Element with a
opacity
value less than1
(See the specification for opacity).- Element with a
mix-blend-mode
value other thannormal
.- Element with any of the following properties with value other than
none
:
transform
filter
perspective
clip-path
mask
/mask-image
/mask-border
- Element with a
isolation
valueisolate
.- Element with a
-webkit-overflow-scrolling
valuetouch
.- Element with a
will-change
value specifying any property that would create a stacking context on non-initial value (see this post).- Element with a
contain
value oflayout
, orpaint
, or a composite value that includes either of them (i.e.contain: strict
,contain: content
).
Your options for getting around this limitation include:
fixed
.mix-blend-mode
to the parent that has created the new stacking context rather than a child of that stacking context.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With