问题
I am trying to acheive Pure CSS scrolling shadows using background-attachment: local but with a background colour on the items that are being scrolled. I was inspired by this article http://lea.verou.me/2012/04/background-attachment-local/ but in their example they do not have a background colour on the child elements.
The problem is that the child elements are above the parent on the z-index scale which means their background colour covers the shadow effect. I know that I can cheat this by having a top and bottom padding on the parent element but this is not a practical solution.
See below for a demo and my code. Any help would be awesome. Many thanks. Clean jQuery answers which offer cross browser support would also be welcomed.
CODEPEN DEMO
HTML
<div class="flow">
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
<div>Test</div>
</div>
CSS
.flow {
background:
linear-gradient(white 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), white 70%) 0 100%,
radial-gradient(50% 0, farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(50% 100%,farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background:
linear-gradient(white 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), white 70%) 0 100%,
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background-repeat: no-repeat;
background-color: white;
background-size: 100% 60px, 100% 60px, 100% 10px, 100% 10px;
background-attachment: local, local, scroll, scroll;
margin: 40px auto;
max-height: 200px;
overflow: auto;
width: 200px;
}
.flow > div {
padding: 10px;
}
回答1:
Why don't you modify the gradients of the parent element itself? As the author is simulating the shadow effect using the radial gradient, there is no physical element present so that you can play with the z-index
, read ahead if you want a jQuery solution for the same.
Demo
Demo (Users who hate codepen just like I do)
Note: These demo's won't work on Firefox < 25.0 as it's using local
value for background-attachment
property
Credits : For Support Chart
Please use Chrome to test, if you want a cross browser solution, refer to my jQuery demonstration.
.flow {
background:
linear-gradient(#f00 30%, rgba(255,0,0,0)),
linear-gradient(rgba(255,0,0,0), #f00 70%) 0 100%,
radial-gradient(50% 0, farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(50% 100%,farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background:
linear-gradient(#f00 30%, rgba(255,0,0,0)),
linear-gradient(rgba(255,0,0,0), #f00 70%) 0 100%,
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background-repeat: no-repeat;
background-color: #f00;
background-size: 100% 60px, 100% 60px, 100% 10px, 100% 10px;
background-attachment: local, local, scroll, scroll;
margin: 40px auto;
max-height: 200px;
overflow: auto;
width: 200px;
}
Note: You can minify this, for example, values like
rgba(255,0,0,0)
can be simply written as#f00
Ok, so the first part of my answer covered the solution by tweaking the gradients which were used by the author itself, I will decode them for you later, as of now, we will use the same trick but using jQuery.
jQuery
$(document).ready(function(){
$('.data-holder').scroll(function(){
$("#shadow, #whitish").css({'top': $('.data-holder').scrollTop() + 'px'});
var y = $('.data-holder').scrollTop();
if( y > 0 ){
$("#shadow").show();
} else {
$("#shadow").hide();
}
});
});
CSS
.data-holder {
width: 200px;
height: 300px;
border: 1px solid #ddd;
overflow: auto;
position: relative;
}
#shadow {
position: absolute;
left: 0;
height: 30px;
width: 180px;
z-index: 9999;
display: none;
background: radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
}
#shadow + div {
padding-top: 10px;
}
#whitish {
background: #fff;
position: absolute;
top: 0;
width: 100%;
height: 10px;
z-index: 999999;
}
.block {
background: #f00;
}
So here, in the above jQuery code we use the first which is $('.data-holder').scroll()
means invoke the function
when the element having a class
of .data-holder
is scrolled, moving ahead, we have the line below
$("#shadow, #whitish").css({'top': $('.data-holder').scrollTop() + 'px'});
Which am using to tweak their top
value onscroll as you know that fixed
position elements are only relative to the viewport and not relative to the element, but absolute
positioned elements are so we use position: absolute;
and tweak the top
using that code, moving ahead, we have the block here
var y = $('.data-holder').scrollTop();
if( y > 0 ){
$("#shadow").show();
} else {
$("#shadow").hide();
}
So here, this does nothing but shows the shadow, once you start scrolling, so it simply means show an element having an id
of #shadow
after user scrolls the element having a class
of .data-holder
when exceeds 0px
.
jQuery Demo (Deliberately used white background there, refer next demo for a standard one, you can get rid of the whitish
element if you don't require a spare top
)
Demo 2
Now, I've applied the background
to the child elements as well, so why does this work and the pure CSS solution doesn't? Well, you picked the code from the website but you missed to read the article, the article clearly states that the author uses radial background to simulate the shadow effect along with rgba
values which plays a crucial role there in making the sides of the radials opaque... which are then dragged along using background-attachment
property with a value of local
, so indeed, when you assign a background to the child elements, it will overlap the background
of the parent element, and hence it fails, even using z-index
won't work there, as there is no literal element used by the author, unlike am using the one with jQuery.
Second question was about the z-index
which I already said that it won't work in my comments as well, because the child element exists in the different stacking context.. So something like this won't work, the parent will just overlap the child, so are you looking to hide the child elements by assigning a negative z-index
?
<div class="parent">
<div class="child"></div>
</div>
.parent {
height: 300px;
width: 300px;
border: 1px solid #f00;
}
.child {
border: 1px solid #000;
height: 40px;
width: 40px;
z-index: -1;
position: relative;
}
Demo
But anyways, here, there is no question of z-index
, so I hope my solutions are clear and I've well explained the thing, you can feel free to ask me if you bump at some point.
来源:https://stackoverflow.com/questions/21164303/background-attachment-local-how-to-have-child-elements-with-background-colours