Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide overflow behind stacked div with transparent background on top of body with SVG background

I have a layout that contains a fixed div (#navigation) that has buttons. The layout also includes scrollable content (.card).

#navigation currently has a green background for demo purposes. Like so:

#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  background: green;
  padding: 25px;
}
<div id="navigation"><button id="btn1">Button</button>
  <button id="btn2">Button</button>
  <button id="btn3">Button</button>
  <button id="btn4">Button</button>
</div>

I would like to hide the any part of any .card element as soon as it goes behind the green background. So, I use z-index stacking order and it works well. Like so:

#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  z-index: 1;
  background: green;
  padding: 25px;
}

#main {
  text-align: center;
}
<div id="main">

  <div id="navigation"><button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>

However, I would also like not to use the green background in production. This means that #navigation should not have a background and only the buttons inside should be visible.

So my question is how do I hide the top-side overflow from #card-wrapper as soon as it reaches the hypothetical green background?

#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  z-index: 1;
  padding: 25px;
  border: 1px solid;
  background: transparent
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
}
<div id="main">

  <div id="navigation"><button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>

Note, the body element has an SVG background, I cannot add any background to #navigation as it would look bad.

I am open to all solutions CSS/JS/jQuery as long as they do not involve hard-coded values

like image 968
I haz kode Avatar asked Nov 24 '17 05:11

I haz kode


Video Answer


2 Answers

Try to set same background for #navigation also, with same background-position (see example below)

#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  padding: 40px 25px 25px 25px;
  background: #ffffff url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
  background-size: cover;
  background-position: 0 0;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: #ffffff url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
  background-size: cover;
  background-position: 0 0;
}
<div id="main">

  <div id="navigation">
    <button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>
like image 55
kastriotcunaku Avatar answered Sep 27 '22 16:09

kastriotcunaku


A JavaScript Solution

The spirit of the solution:

Tested on CH62, FF57 and IE11

While kastriotcunaku's answer is good if you don't mind the formatting, This solution maintain same parameters as those given, here I'll attempt to give the #navigation a background that looks and is positioned as the body's to give the illusion of transparency using JavaScript to make it responsive.

Background-size:cover on the #navigation div will make it looks denser. So I'll try to emulate cover by stretching the background to cover the whole body and still appearing only on the navigation element by :

navigationElement.style.backgroundSize=(document.body.clientHeight/imgH)*imgW+"px";

/* imgW image width, imgH original image height. A trick to maintain the width/height ratio of the SVG. You can programmaticallyget size of the image
For some reason I've needed that even on the body for IE11 who doesn't seem to handle "cover" properly */

For the background positioning however, there are browser differences. Surprisingly enough IE11 is the most straightforward

    n=document.getElementById('navigation');    
    var isChrome = !!window.chrome && !!window.chrome.webstore;
    var isIE = /*@cc_on!@*/false || !!document.documentMode;
    var imgH=647.7;
    var imgW= 2351.2;

       function resizeHandler(){ 
            r=n.getBoundingClientRect();
            n.style.backgroundSize=(innerHeight/imgH)*imgW+"px";
            if (isChrome){
                n.style.backgroundPosition=r.width/2+"px 0px"
            } else if (isIE){
                n.style.backgroundPosition=0
        document.body.style.backgroundSize=(innerHeight/imgH)*imgW+"px";
            } else{
                n.style.backgroundPosition=-r.x+"px -20px"
            }
       }    
       addEventListener("resize",resizeHandler);
       document.addEventListener ("DOMContentLoaded",resizeHandler);
       
       
#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  z-index: 1;
  padding: 25px;
  border: 0.1px dotted;     
  background: #ffffff url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background:#ffffff  url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
  background-position:0;
}
<div id="main">

  <div id="navigation">
    <button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>
like image 33
user10089632 Avatar answered Sep 27 '22 17:09

user10089632