atomictom
atomictom

Reputation: 1807

Does `position: fixed` break mix-blend-mode, and is there a workaround?

I'm trying to get box-shadows playing nicely with different backgrounds. The standard way seems to be using mix-blend-mode, and applying a fake div behind the real one with the effect.

An example of this technique here (click the + icon in the top right).

If I alter this code slightly to wrap the non-background elements into a container with position: fixed it breaks, example here. Note, position: absolute works fine.

I do need a structure like the example, a parent that's position-fixed and blend that can accommodate variable heights or widths and multiple instances of the .box element. I can hazard a rough guess why it doesn't work (fixed breaks it out of the doc flow and therefore there's nothing to blend), I can't see a way round it though.

Another example I made that reduces things a bit more, note how if you comment out position-fixed it works fine:

.blend {
  height: 100%;
  box-shadow: 0 4px 8px 0 rgba(156, 156, 156, 0.7);
  mix-blend-mode: multiply;
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
}

.box {
  background: grey;
  min-height: 10px;
  width: 100%;
  position: relative;
  margin: 0 0 15px;
}

.container {
  /* using absolute works */
  position: absolute;
  /* using fixed does not work */
  position: fixed;
  height: 50%;
  width: 50%;
}

html {
  height: 100%;
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  margin: 0;
}

.column {
  position: relative;
  width: 50%;
  height: 100%;
}

.left {
  background: #2D2D2D;
}

.right {
  background: #f6f6f6;
}
<div class="column left"></div>
<div class="column right"></div>

<div class="container">
  <div class="box">
    text
    <div class="blend"></div>
  </div>
  <div class="box">
    text<br /><br />more text
    <div class="blend"></div>
  </div>
</div>

(I saw a previous question, which looks along similar lines but I couldn't get their example to work to check)

Upvotes: 1

Views: 4845

Answers (2)

cdoublev
cdoublev

Reputation: 784

3.2. Behavior specific to HTML

Everything in CSS that creates a stacking context must be considered an ‘isolated’ group. HTML elements themselves should not create groups. An element that has blending applied, must blend with all the underlying content of the stacking context that that element belongs to.

Eg. position: fixed will create a stacking context (isolated group).

https://drafts.fxtf.org/compositing-1/#csscompositingrules_CSS

Related answer more specific on stacking context: https://stackoverflow.com/a/56545440/7947839

Upvotes: 1

Diego Alfaro
Diego Alfaro

Reputation: 21

You can move the blend element out of the container and make it fixed with the same dimensions as container.

Checkout the snippet:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>

html{
  height:100%;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  margin: 0;
}

.column {
  position: relative;
  width: 50%;
  height: 100%;
}

.left {
  background: #2D2D2D;
}

.right {
  background: #f6f6f6;
}

.blend {
  box-shadow: 0 4px 8px 0 rgba(156, 156, 156, 0.7);
  mix-blend-mode: multiply;
  position: fixed;
  height: 50%;
  width: 50%;
}

.box {
  background: grey;
  height: 100%;
  width: 100%;
  position: absolute;
}

.container {
  position: fixed;
  height: 50%;
  width: 50%;
}


</style>
</head>
<body>

<div class="column left"></div>
<div class="column right"></div>

<div class="blend"></div>
<div class="container">
	
  <div class="box">
    text
  </div>
</div>

</body>
</html>

Upvotes: 2

Related Questions