How to add upper and lower shadow while scrolling, but only if necessary?

How to add shadow when overflowing the container, but only if necessary?

I mean:

  • if content is available for scrolling up or down, show a shadow to tell the user that there is more content for scoll
  • If there is no scrolling content, the shadow will not appear

And clarify further

  • if the content of the container is full (i.e., it scrolls), and the user is on the very top of the content, then there should be a shadow at the bottom of the page, not the top.
  • The same thing happens if the user is at the bottom of the page, expecting that there will be a shadow at the top.
  • If the contents do not overflow the container, then do not show a shadow to maintain cleanliness.

I have working javascript solutions, but I want something purely css for performance reasons.

Any ideas?

+19
source share
3 answers

I think you are looking for something like this;

Link: LINK

html { background: white; font: 120% sans-serif; } .scrollbox { overflow: auto; width: 200px; max-height: 200px; margin: 50px auto; background: /* Shadow covers */ linear-gradient(white 30%, rgba(255, 255, 255, 0)), linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%, /* Shadows */ 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: /* Shadow covers */ linear-gradient(white 30%, rgba(255, 255, 255, 0)), linear-gradient(rgba(255, 255, 255, 0), white 70%) 0 100%, /* Shadows */ 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% 40px, 100% 40px, 100% 14px, 100% 14px; /* Opera does not support this in the shorthand */ background-attachment: local, local, scroll, scroll; } 
 <div class="scrollbox"> <ul> <li>I Show Below Shadow. Go Down Now</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> <li>16</li> <li>17</li> <li>18</li> <li>19</li> <li>20</li> <li>The end!</li> <li>No shadow here. See Above. Go Up</li> </ul> </div> 

+11
source

I apologize for answering my own question, but after some googling, I found a good CSS-only solution that works in chrome on macOS.

@Hash provided a solution taken from the lea verou blog. Her solution uses background-attachment: local to achieve the effect, however this is currently interrupted in chrome 59 on macOS ?? (He worked in 2012, but not in 2017 for me, at least for now). However, her solution is excellent, and you should read more about it here .

In her article (from 2012), she refers to an older but more compatible solution that uses pseudo-elements. This blog post is from Roman Komarov and here are some direct quotes from his article .

Here is an old idea, but recreated with pure CSS.

Initially, I had an extra wrapper and two additional pseudo-elements. Later, I decided to rewrite the code and use only one element (using radial gradients).

Although this method is simple, there are some limitations:

  • the background should be solid
    • however, if you try background-attachment: fixed ...)
  • there are some problems with positioning

But in most cases, this method is pretty bulletproof.

If you replace CSS gradients with simple images, this method may work in IE. (A few more minor fixes may be required, I did not check.)

And here is what code is copied directly from his blog:

 html { background: #FFF; } .scrollbox { position: relative; z-index: 1; overflow: auto; width: 200px; max-height: 200px; margin: 50px auto; background: #FFF no-repeat; background-image: -webkit-radial-gradient(50% 0, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)), -webkit-radial-gradient(50% 100%, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)); background-image: -moz-radial-gradient(50% 0, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)), -moz-radial-gradient(50% 100%, farthest-side, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)); background-image: radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)), radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)); background-position: 0 0, 0 100%; background-size: 100% 14px; } .scrollbox:before, .scrollbox:after { content: ""; position: relative; z-index: -1; display: block; height: 30px; margin: 0 0 -30px; background: -webkit-linear-gradient(top, #FFF, #FFF 30%, rgba(255, 255, 255, 0)); background: -moz-linear-gradient(top, #FFF, #FFF 30%, rgba(255, 255, 255, 0)); background: linear-gradient(to bottom, #FFF, #FFF 30%, rgba(255, 255, 255, 0)); } .scrollbox:after { margin: -30px 0 0; background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0), #FFF 70%, #FFF); background: -moz-linear-gradient(top, rgba(255, 255, 255, 0), #FFF 70%, #FFF); background: linear-gradient(to bottom, rgba(255, 255, 255, 0), #FFF 70%, #FFF); } 
 <div class="scrollbox"> <ul> <li>Not enough content to scroll</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> </div> <div class="scrollbox"> <ul> <li>Ah! Scroll below!</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>The end!</li> <li>No shadow there.</li> </ul> </div> 
+18
source

Here is the pure CSS solution that I put together that casts a shadow over the content, not behind it.

 /* Stuff that does not matter */ html { font-size: 16px; } body { margin: 0; padding: 0; font: 1rem/1.5 arial, sans-serif; } .c-container { width: 100%; max-width: 400px; margin: 0 auto; padding: 0 2rem; box-sizing: border-box; } .c-header { width: 100%; padding: 1rem 0; background: white; } .c-header_heading { margin: 0; font-size: 2rem; font-weight: bold; } /* Stuff that matters */ .c-scrollbox { position: relative; width: 100%; height: 200px; overflow: scroll; } .c-scrollbox::before { content: ''; position: -webkit-sticky; position: sticky; top: 0; display: block; height: 1px; background: rgba(0,0,0,.32); } .c-scrollbox::after { content: ''; position: absolute; top: 0; display: block; width: 100%; height: 1rem; background: linear-gradient(rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); } 
 <div class="c-container"> <header class="c-header"> <h1 class="c-header_heading">Shadow on Scroll</h1> </header> <div class="c-scrollbox"> <p>Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ullamcorper nulla non metus auctor fringilla. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p> <p>Donec id elit non mi porta gravida at eget metus. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> <p>Vestibulum id ligula porta felis euismod semper. Nullam quis risus eget urna mollis ornare vel eu leo. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam quis risus eget urna mollis ornare vel eu leo. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</p> <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Nulla vitae elit libero, a pharetra augue. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p> </div> </div> 

0
source

Source: https://habr.com/ru/post/1269280/


All Articles