[英]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>
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功能,如
clip
或backdrop-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: 不幸的是,这有不利之处:
#screen
element to match the #navigation
element - this could be avoided if the width/height/position of the #screen
element was known in advance #screen
元素的尺寸以匹配#navigation
元素 - 如果提前知道#screen
元素的宽度/高度/位置,则可以避免这种情况 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.