Go further

A little known fact but position: fixed can be cropped by clip: rect() property! See

So that

.selector { position: absolute; clip: rect(0, auto, auto, 0); width: 100px; height: 100px; } .selector:before { content: ''; position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: -1; background-image: linear-gradient(white, black); background-size: cover; }

Single rule - parent element must be position: absolute or position: fixed , otherwise clip: rect() won't crop.

But because of that limitation all .selector at mobile devise must be position: absolute while desktop version does not have this restriction. This is not convenient at all. Elements must behave identically for both desktop and mobiles and does not contain extra conditions.

That's why Multiple.js was written, this little JS plugin takes care about all those markup differences, browser specific workarounds, vendor-prefixes, etc.. for you. All you left to do is simply specify selector and background.

If for some reason you decide to avoid JS plugin, want only pick styles and do all markup work by yourself, here are starting material for you:

Show markup/styles For desktop Codepen <div class="selector multiple-desktop">Your content</div> /* where .selector is your element. * Give it any styles you need (any display, position, sizes...) * Set appropriate background-image to .multiple-desktop, don't forget about vendor prefixes. */ .selector { width: 100px; height: 100px; } .multiple-desktop { /* background-image: linear-gradient(rgba(133, 149, 232, 0.58), rgba(0,0,0, .5)); */ background-size: cover; background-position: center; background-attachment: fixed; background-repeat: no-repeat; } For mobile Codepen <div class="selector"> <div class="multiple-mobile-wrapper"> <div class="multiple-mobile"></div> <div class="multiple-mobile-content">Your content</div> </div> </div>

/* where .selector is your element. * Give it any styles you need (any display, position, sizes...) * Set appropriate background-image to .multiple-mobile:before, don't forget about vendor prefixes. */ .selector { width: 100px; height: 100px; } .multiple-mobile-wrapper { position: relative; height: 100%; } .multiple-mobile-content { height: 100%; } .multiple-mobile { clip: rect(0 auto auto 0); clip: rect(0, auto, auto, 0); -webkit-mask-image: -webkit-linear-gradient(top, #fff 0%, #fff 100%); -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); overflow: hidden; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; } .multiple-mobile:before { content: ''; /* background-image: linear-gradient(rgba(133, 149, 232, 0.58), rgba(0,0,0, .5)); */ background-size: cover; background-position: center; background-repeat: no-repeat; position: fixed; top: 0; right: 0; bottom: 0; left: 0; }

And, in addition to that I'd like to share thoughts about customizing viewport size.

As you know background-attachment: fixed depends on viewport size, so background fills all screen from top left to bottom right point. Such background does not react on scroll, visually static and always located in the same place. Sometimes this behaviour is not what we need. Let's assume our whole background image must be strictly fit at element with sizes 500px x 500px (when actual viewport is 1920x1080). Or you need background to scroll with the page (as by default).

See examples to understand the difference:

From this (background is stretched to full-page viewport and keeps fixed on scroll while container size is restricted, so that background isn't fit wholly in container)

(background is stretched to full-page viewport and keeps fixed on scroll while container size is restricted, so that background isn't fit wholly in container) To this (background is stretched to container size so is fully fit and keeps scrolls with the page)

Any ideas how to do that?