简体   繁体   English

隐藏在堆积的div后面溢出与透明背景在身体顶部有SVG背景

[英]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. 我有一个包含fixed div( #navigation )的布局,其中包含按钮。 The layout also includes scrollable content ( .card ). 布局还包括可滚动内容( .card )。

#navigation currently has a green background for demo purposes. #navigation目前有一个绿色背景用于演示目的。 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. 我想在绿色背景后面隐藏任何.card元素的任何部分。 So, I use z-index stacking order and it works well. 所以,我使用z-index堆叠顺序,它运作良好。 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. 这意味着#navigation不应该有背景,只有里面的按钮应该是可见的。

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的顶部溢出?

 #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. 注意, body元素有一个SVG背景,我不能为#navigation添加任何背景,因为它看起来很糟糕。

I am open to all solutions CSS/JS/jQuery as long as they do not involve hard-coded values 我对所有解决方案CSS / JS / jQuery持开放态度,只要它们不涉及硬编码值

Try to set same background for #navigation also, with same background-position (see example below) 尝试为#navigation设置相同的背景,具有相同的背景位置(参见下面的示例)

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

A JavaScript Solution 一个JavaScript解决方案

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. 虽然kastriotcunaku的答案是好的,如果你不介意格式化,这个解决方案保持与给定的相同的参数,在这里我将尝试给#navigation一个看起来和定位为正文的背景,以给出透明度的幻觉使用JavaScript使其响应。

Background-size:cover on the #navigation div will make it looks denser. Background-size:cover #navigation div上的Background-size:cover会使它看起来更密集。 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 : 因此,我将尝试通过拉伸背景来覆盖整个身体来模仿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 /* 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 /* 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 */

For the background positioning however, there are browser differences. 然而,对于背景定位,存在浏览器差异。 Surprisingly enough IE11 is the most straightforward 令人惊讶的是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> 

I really, really, really, really wanted to find a solution using some new CSS features like clip or backdrop-filter . 我真的,真的,真的,真的想找到一个使用一些新的CSS功能,如clipbackdrop-filter的解决方案。 In the end, I found a solution but it definitely comes up short, and isn't as elegant as kastriotcunaku's solution. 最后,我找到了一个解决方案,但它确实很短,并不像kastriotcunaku的解决方案那么优雅。

The solution below uses the experimental backdrop-filter property to make the content behind a #screen element have opacity(0) . 下面的解决方案使用实验的backdrop-filter属性使#screen元素后面的内容具有opacity(0) Unfortunately, there are downsides to this: 不幸的是,这有不利之处:

  • Requires a few lines of JavaScript to set the dimensions of the #screen element to match the #navigation element - this could be avoided if the width/height/position of the #screen element was known in advance 需要几行JavaScript来设置#screen元素的尺寸以匹配#navigation元素 - 如果提前知道#screen元素的宽度/高度/位置,则可以避免这种情况
  • Will only work in browsers supporting the backdrop-filter property - mainly Safari, or in Chrome with the Experimental Web Platform features flag enabled (which you can set by going to chrome://flags/#enable-experimental-web-platform-features in Chrome) 仅适用于支持backdrop-filter属性的浏览backdrop-filter - 主要是Safari,或者在启用了实验性Web平台功能标记的Chrome中(可以通过转到chrome:// flags / #enable-experimental-web-platform-features设置)在Chrome中)

The end result is: 最终结果是:

在此输入图像描述

If you're using a browser with support for backdrop-filter you can view it in action below: 如果您使用的是支持backdrop-filter的浏览器,则可以在下面的操作中查看:

 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"; 
 #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; } 
 <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> 

If the width/height of the #screen and #navigation are fixed we do away with the JavaScript. 如果#screen#navigation的宽度/高度是固定的,我们将取消JavaScript。

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

You can use your navigation as fixed navigation and only allow scroll to your content area. 您可以将导航用作固定导航,只允许滚动到您的内容区域。 For that you have to add position: absolute; 为此你必须添加position: absolute; to #card-wrapper and remove display:inline-block from .card . #card-wrapper并从.card删除display:inline-block

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

After a nice bit of trial and errors, I've got this solution that I think it's the best so far 经过一段时间的试验和错误,我得到了这个解决方案,我认为它是目前为止最好的

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

If you don't mind to have fixed value for the height of the buttons - then your task can be solved through background-clip style. 如果您不介意为按钮的height设置固定值 - 那么您的任务可以通过background-clip样式来解决。 In example below I've also added click handlers for cards and buttons to demonstrate that cards are still clickable. 在下面的示例中,我还添加了卡片和按钮的点击处理程序,以证明卡片仍然可以点击。

 $('.card').on('click',function(){ $(this).addClass('clicked'); }) $('button').on('click',function(){ $('.card').removeClass('clicked'); }) 
 #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; } 
 <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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM