skip to Main Content

I want a gradient to stick to the top of my scrolling div.

If I try to use position absolute, it works when scrolled to the top, but when you scroll, the gradient scrolls away:

div {
background-color: red;
width: 200px;
height: 200px;
overflow-y: scroll;
position: relative;
}

p {
border: solid 1px blue;
height: 300px;
}

div::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 1em;
    background: linear-gradient(to bottom, green, transparent);
}
<div>
<p>hello</p>
</div>

The fix seems to be to use sticky, which makes it stick to the top no matter the scroll position:

div {
background-color: red;
width: 200px;
height: 200px;
overflow-y: scroll;
position: relative;
}

p {
border: solid 1px blue;
height: 300px;
}

div::before {
    content: '';
    position: sticky;
    top: 0;
    left: 0;
    width: 100%;
    height: 1em;
    background: linear-gradient(to bottom, green, transparent);
    display: block;
}
<div>
<p>hello</p>
</div>

The problem with this method is when you are scrolled to the top, the gradient appears above the top element, instead of layered on top of it.

Is there any proper way to do this, or a way to fix it without adding more wrappers?

2

Answers


  1. Instead of positioning the gradient background-image above the div with a pseudo-element, use it for the div itself.

    div {
      background-image: linear-gradient(to bottom, green, red 1em);
      width: 200px;
      height: 200px;
      overflow-y: scroll;
      position: relative;
    }
    
    p {
      border: solid 1px blue;
      height: 300px;
    }
    <div>
      <p>hello</p>
    </div>

    Maybe you want to remove the margin of the p as well?

    div {
      background-image: linear-gradient(to bottom, green, red 1em);
      width: 200px;
      height: 200px;
      overflow-y: scroll;
      position: relative;
    }
    
    p {
      border: solid 1px blue;
      height: 300px;
      margin: 0;
    }
    <div>
      <p>hello</p>
    </div>
    Login or Signup to reply.
  2. .App {
      text-align: center;
      height: 200px;
      border: 1px solid red;
      overflow-y: scroll;
    }
    .bg {
      height: 1em;
      width: 100%;
      position: fixed;
      top: 10px;
      background: linear-gradient(to bottom, green, transparent);
    }
    
    .header {
      height: 300px;
      z-index: 10;
      border: solid 1px blue;
    }
    <div class="App">
      <div class="bg" />
      <h1 class="header">Hello CodeSandbox</h1>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search