jQuery Fallback Support for the CSS Property "background-attachment: local" I have made some jQuery Fallback Support for the CSS Property "background-attachment: local" and I am mainly a CSS developer. I do some jQuery, but I thought I would check to see if I am doing this in the more efficient way, as I may have multiple versions of this on one page.

CODEPEN DEMO

HTML

&lt;div class="container"&gt;
  &lt;div class="data-holder"&gt;
    &lt;div id="shadowtop"&gt;&lt;/div&gt;
    &lt;div id="shadowbottom"&gt;&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
    &lt;div class="block"&gt;hello&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


CSS

@import "http://fonts.googleapis.com/css?family=Open+Sans:400,600,700";
* {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}
body {
    background: none repeat scroll 0 0 #fff;
    font-family: "Open Sans";
    line-height: 26px;
    margin: 20px;
}

.container {
  position: relative;
  margin-top: 30px;
}

.data-holder {
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
  width: 200px;
  height: 300px;
  overflow: auto;
}

#shadowtop,
#shadowbottom {
  position: absolute;
  left: 0;
  height: 12px;
  width: 180px;
  z-index: 9999;
  display: none;
  background-size: 100% 12px;

}
#shadowtop {
  top: 0;
  background:   radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.15), rgba(0,0,0,0)) 0 100%;
}
#shadowbottom {
  bottom: 0;
  background:   radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.15), rgba(0,0,0,0)) 0 100%;
}

.block {
  background: #fff;
  border-bottom: 1px solid #f4f4f4;
  padding: 10px;
}
.block:last-child {
  border-bottom: 0 none;
}


jQuery

$(document).ready(function(){
  $('.data-holder').scroll(function(){
    var scrollValue = $(this).scrollTop();
    var elementHeight = $(this).height();
    if(scrollValue == 0){
      $("#shadowtop").fadeOut(200);
      console.log("at top");  //should remove
    } else if (scrollValue == ($(this).get(0).scrollHeight - $(this).height())){
      $("#shadowbottom").fadeOut(200);
      console.log("at bottom"); //should remove
    } else {
      console.log("in middle"); //should remove
      $("#shadowtop").fadeIn(200);
      $("#shadowbottom").fadeIn(200);
    }
  });
  var scrollValue = $('.data-holder').scrollTop();
  if(scrollValue &lt; ($('.data-holder').get(0).scrollHeight - $('.data-holder').height())){
     $("#shadowbottom").show();
  }
});
This code annoyed me for a while, the part outside of the initialization does not belong and it seemed silly to add it to the listener. Plus, the code outside of the listener will mess up when you have multiple data-holder elements.

Then I realized that I could take a different approach, do this in 2 steps:


Determine whether I should hide or show the top
Determine whether I should hide or show the bottom


Then, I do not need the piece of code outside of the listener, and it becomes cleaner.
Also, the 200 has to be a constant, also I would take only the #shadowbottom and #shadowtop belonging to the .data-holder.

So, in all, I would counter propose:

$(document).ready(function(){
  var fadeSpeed = 200;
  $('.data-holder').scroll(function(){
    var scrollValue = $(this).scrollTop(),
        elementHeight = $(this).height(),
        $top = $(this).children('#shadowtop'),
        $bottom = $(this).children('#shadowbottom'),
        atTop = (scrollValue == 0),
        atBottom = (scrollValue == ( this.scrollHeight - elementHeight));
    (atTop)   ? $top.fadeOut( fadeSpeed )    : $top.fadeIn( fadeSpeed );
    (atBottom)? $bottom.fadeOut( fadeSpeed ) : $bottom.fadeIn( fadeSpeed );
  }).scroll();
});


I was mildly worried that with each scroll event the top / bottom might flicker because of the repeated fadeIn() calls, but I can tell from your CodePen that does not happen, so there is nothing to worry about there.

Finally, I did not look at your CSS as you actually are a CSS developer and also I did not test my code, but I am confident you get where I am going with this.