I had the same issue you had and struggled with it almost 3 days. But as of June 2020 and improving on @AGrush's answer, here is a reliable solution I found for this that works on all devices and has 100% browser compatibility. It allows the desired effect in any place of the page and not just the top or bottom of the page, and you can create as many as you need or want.
This also addresses the different issues provided by @Ylama, @Cruz-Nunez, @Tim and @LWRMS answers that rely on device media queries that, as you know, have no standards and vary on many new devices. And also avoids the use of pseudo elements that I have never been really able to work with, as with the solutions proposed by @MugenFTW and @Gianni Unz.
The only known issue so far is with this option is in safari. The browser repaints the whole image on every scroll movement so it puts a heavy burden on graphics and most of the time makes the image flicker up and down some 10px. There is literally no fix for this, but i think there is also no better response for your inquire.
I hope this works for you. You can check the results live in www.theargw.com, where i have three different fixed background images.
body, .black {
width: 100%;
height: 200px;
background: black;
}
.e-with-fixed-bg {
width: 100%;
height: 300px;
/* Important */
position: relative;
}
.bg-wrap {
clip: rect(0, auto, auto, 0);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.bg {
position: fixed;
display: block;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center center;
background-image: url(https://images.pexels.com/photos/949587/pexels-photo-949587.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500);
transform: translateZ(0);
will-change: transform;
}
.e-container {
z-index: 1;
color: white;
background: transparent;
}
<div class="black"></div>
<div class="e-with-fixed-bg">
<div class="bg-wrap">
<div class="bg"></div>
</div>
<div class="e-container">
<h1>This works well enought</h1>
</div>
</div>
<div class="black"></div>
--------------------- EDIT --------------------- The code posted was missing the background wrapper that allows the background to not change size and maintain the fixed position. Sorry to post the wrong code this morning guys! But here is the change.