神刀安全网

Multiple.js – exp. of sharing background over multiple elements by pure CSS/HTML

.selector {   background-image: linear-gradient(white, black);   background-size: cover;   background-position: center;   background-attachment: fixed;  /* <- here it is */    width: 100px;   height: 100px; }

Idea is just that simple!

background-attachment: fixed expands background to viewport’s size and displays in every element appropriate chunk, exactly what is needed!

But here we stumble upon a problem with mobile devices, as far as they seems to ignore background-attachment: fixed property for performance reasons . Background behaves as with default value background-attachment: scroll . And in addition to that there are even no way to detect support of this property.

So how to handle this flaw at mobile devices? Think a bit on possible workaround and click a button below.

Mobile workaround

I bet the first thing you think was position: fixed; z-index: -1; trick because this is frequent solution for such background-related cases.

Ok, let’s assume we’ve added pseudo element with such styles

.selector {   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; }

Background has been successfully expanded to full viewport size . But we need to display only that chunk of background under .selector element. It turns out that background outside of .selector element must be cropped.

But how to do that? .selector { overflow: hidden; } won’t do the trick because it’s descendant is position: fixed . Check out by yourself at Codepen

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 1920×1080). Or you need background scroll with the page (as by default).

See examples to understand the difference:

  • From(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(background is stretched to container size so is fully fit and keeps scrolls with the page)

Any ideas how to do that?

Go ahead

And the answer is: Iframe !

It was a surprise for me to find out that iframe has it’s own viewport, I just didn’t thought about this from this point of view before. Wrapping the content into iframe and setting iframe specific sizes – and background will fill iframe’s size, not parent page viewport size. Check out real examples:without iframe,with iframe. To do that easily may be used convenient iframe-resizer library that observes iframe’s inner content height and change iframe height accordingly.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Multiple.js – exp. of sharing background over multiple elements by pure CSS/HTML

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮