使用SVG背景

时间:2017-11-24 05:44:29

标签: javascript jquery css

我的布局包含一个带有按钮的fixed div(#navigation)。布局还包括可滚动内容(.card)。

#navigation目前有绿色背景用于演示目的。像这样:

#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>

我想隐藏任何.card元素的任何部分,只要它在绿色背景后面。所以,我使用z-index堆叠顺序,它运作良好。像这样:

#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>

但是,我也不想在生产中使用绿色背景。这意味着#navigation不应该有背景,只有里面的按钮可见。

所以我的问题是,一旦到达假设的绿色背景,我如何隐藏#card-wrapper的顶部溢出?

#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>

请注意,body元素具有SVG背景,我无法向#navigation添加任何背景,因为它看起来很糟糕。

我对所有解决方案CSS / JS / jQuery持开放态度,只要它们不涉及硬编码值

6 个答案:

答案 0 :(得分:15)

尝试为#navigation设置相同的背景,具有相同的背景位置(参见下面的示例)

&#13;
&#13;
#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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

JavaScript解决方案

解决方案的精神:

Tested on CH62, FF57 and IE11

如果您不介意格式化,kastriotcunaku的答案是好的, 该解决方案保持与给定的参数相同, 在这里,我将尝试给#navigation一个看起来和定位为正文的背景,以使用JavaScript来提供透明的幻觉,使其具有响应性。

Background-size:cover div上的

#navigation会让它看起来更密集。因此,我将尝试通过拉伸背景来覆盖整个身体来模仿cover,并且仍然只出现在导航元素上:

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 programmatically get 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 */

然而,对于背景定位,存在浏览器差异。令人惊讶的是IE11是最直接的

    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>

答案 2 :(得分:2)

我真的,真的,真的,真的想要使用一些新的CSS功能找到解决方案,例如clipbackdrop-filter。最后,我找到了一个解决方案,但它确实很短,并不像kastriotcunaku的解决方案那样优雅。

下面的解决方案使用实验backdrop-filter property来使#screen元素后面的内容具有opacity(0)。不幸的是,这有不利之处:

  • 需要几行JavaScript来设置#screen元素的尺寸以匹配#navigation元素 - 如果#screen元素的宽度/高度/位置,则可以避免这种情况事先知道
  • 仅适用于支持backdrop-filter属性的浏览器 - 主要是Safari,或者在Chrome中启用了实验性网络平台功能标记(您可以通过转到chrome:// flags / #enable-experimental-来设置) Chrome中的网络平台功能)

最终结果是:

enter image description here

如果您使用的是支持backdrop-filter的浏览器,则可以在下方查看以下内容:

&#13;
&#13;
var screen = document.getElementById("screen");
var navigation = document.getElementById("navigation");
var navigationStyle = window.getComputedStyle(navigation, null);

screen.style.height = navigationStyle.getPropertyValue('height');
screen.style.width = navigationStyle.getPropertyValue('width');
screen.style.border = navigationStyle.getPropertyValue('border');
screen.style.borderColor = "transparent";
&#13;
#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

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

#screen,
#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  padding: 25px;
}

#screen {
  backdrop-filter: opacity(0%);
  -webkit-backdrop-filter: opacity(0%);
}

#navigation {
  z-index: 10;
  border: 1px solid;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
}

.bkg {
  position: fixed;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
  
}
&#13;
<div id="main">

  <div id="screen"></div>
  
  <div class="bkg"></div>
  
  <div id="navigation">
    <button id="btn1" onclick="alert()">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>
&#13;
&#13;
&#13;

如果#screen#navigation的宽度/高度已修复,我们将取消JavaScript。

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

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

#screen,
#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  padding: 25px;
  width: 280px;
  height: 71px;
  box-sizing: border-box;
}

#screen {
  backdrop-filter: opacity(0%);
  -webkit-backdrop-filter: opacity(0%);
}

#navigation {
  z-index: 10;
  border: 1px solid;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
}

.bkg {
  position: fixed;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
  
}
&#13;
<div id="main">

  <div id="screen"></div>
  
  <div class="bkg"></div>
  
  <div id="navigation">
    <button id="btn1" onclick="alert()">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>
&#13;
&#13;
&#13;

答案 3 :(得分:2)

您可以将导航用作固定导航,只允许滚动到您的内容区域。为此,您必须将position: absolute;添加到#card-wrapper并从display:inline-block中删除.card

#card-wrapper {
  position: absolute;
  top: 100px;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  clear:both;
}

#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>

答案 4 :(得分:2)

经过一段时间的试验和错误,我得到了这个解决方案,我认为它是目前为止最好的

&#13;
&#13;
#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: 25%;
  right:25%;
  z-index: 1;
  padding: 25px;
  border-top: 0.1px dotted;    
  border-bottom: 0.1px dotted;
  background: white url(http://svgur.com/i/42T.svg) top left/cover no-repeat fixed;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: white url(http://svgur.com/i/42T.svg) top left/cover no-repeat fixed;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 5 :(得分:1)

如果您不介意为height按钮设置固定值,那么您的任务可以通过background-clip样式解决。在下面的示例中,我还添加了卡片和按钮的点击处理程序,以证明卡片仍然可以点击。

&#13;
&#13;
$('.card').on('click',function(){
  $(this).addClass('clicked');
})
$('button').on('click',function(){
  $('.card').removeClass('clicked');
})
&#13;
#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

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

#navigation {
  background-image: url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
  background-size: cover;
  background-clip: content-box;
  border: 0 none;
  padding: 0;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  position: fixed;
  z-index: 1;
  box-sizing: border-box;
/**
calc() calculation values:
 25px - .buttons-list padding  
 20px - top offset of #navigation (it is also padding-top value)
 30px - button height;
*/
  padding: 20px 0 calc(100vh - 25px * 2 - 20px - 30px);
  pointer-events: none;
}

button {
  height: 30px
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
}

.buttons-list {
  padding: 25px;
  pointer-events: initial;
}

/* Just for click events demonstration */
.card.clicked{
  background-color: green;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">

  <div id="navigation">
    <div class="buttons-list">
      <button id="btn1">Button</button>
      <button id="btn2">Button</button>
      <button id="btn3">Button</button>
      <button id="btn4">Button</button>
    </div>
  </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>
&#13;
&#13;
&#13;