Home > Enterprise >  How to display "Scroll down!" if and only if content overflows in pure CSS?
How to display "Scroll down!" if and only if content overflows in pure CSS?

Time:11-28

The closest I could find (for pure CSS) is this:

https://lea.verou.me/2012/04/background-attachment-local/

... which might not be up-to-date any more. I am getting doubts to whether or not this is possible in CSS. This is Lea Verou's code:

/**
 * Scrolling shadows by @kizmarh and @leaverou
 * Only works in browsers supporting background-attachment: local; & CSS gradients
 * Degrades gracefully
 */

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 doesn't support this in the shorthand */
    background-attachment: local, local, scroll, scroll;
}

Not only are the shadows shown, if and only if the content overflows. In addition, the shadows disappear once you scroll all the way to the bottom (or to the top, respectively).

But is it possible to make use of background-attachment: local to control the display-, visibility-, or opacity-properties of some other DOM element?

CodePudding user response:

You can make it happen using CSS pseudo elements:

ul {
  margin: 0px;
}

.scrollbox {
  overflow: auto;
  float: left;
  width: 200px;
  height: 150px;
  margin: 0px 20px;
  font-size: 16px;
  background: /* Shadow covers */
  /* top */
  linear-gradient(white 30%, transparent), /* bottom */
  linear-gradient(transparent, white 70%) 0 100%, /* Shadows */
  radial-gradient(farthest-side at 50% 0, rgba(63, 185, 6, 0.5), transparent), radial-gradient(farthest-side at 50% 100%, rgba(63, 185, 6, 0.5), transparent) 0 100%;
  background-repeat: no-repeat;
  background-color: white;
  background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
  /* Opera doesn't support this in the shorthand */
  background-attachment: local, local, scroll, scroll;
  position: relative;
  border: 1px solid gray;
}

.scrollbox::before {
  content: "scroll up";
  display: block;
  width: 100%;
  position: sticky;
  top: 0;
  text-align: center;
  font-size: 0.5rem;
  height: 0.6rem;
}

.scrollbox::after {
  content: "scroll down";
  display: block;
  width: 100%;
  position: sticky;
  bottom: 0;
  text-align: center;
  font-size: 0.5rem;
  height: 0.6rem;
}

ul::before {
  content: "";
  width: 50%;
  background-color: white;
  position: absolute;
  top: 0;
  z-index: 100;
  height: 0.6rem;
}

ul::after {
  content: "";
  width: 100%;
  background-color: white;
  position: absolute;
  left: 0;
  z-index: 100;
  height: 0.6rem;
}
<div class="scrollbox">
  <ul>
    <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>
  </ul>
</div>
<div class="scrollbox">
  <ul>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
  </ul>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Using the similar idea as the background. scrollbox::before and scrollbox::after elements are showing the up down text. And ul::before and ul::after hiding them at top and bottom.


Using SVG: we can use SVG instead of gradients in background:

ul {
  margin: 0px;
}

.scrollbox {
  overflow: auto;
  width: 200px;
  height: 200px;
  margin: 0px 10px;
  background: /* Shadow covers */
  /* top */
  linear-gradient(white 30%, transparent), /* bottom */
  linear-gradient(transparent, white 70%) 0 100%, /* Shadows */
  url("data:image/svg xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='1rem' width='200px'><text x='50%' y='10' fill='green' font-size='0.7rem' text-align='center'>scroll up</text></svg>"), url("data:image/svg xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='1rem' width='200px'><text x='50%' y='10' fill='green' font-size='0.7rem' text-align='center'>scroll down</text></svg>") 0 100%;
  background-repeat: no-repeat;
  background-color: white;
  background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
  /* Opera doesn't support this in the shorthand */
  background-attachment: local, local, scroll, scroll;
  border: 1px solid gray;
  float: left;
}
<div class="scrollbox">
  <ul>
    <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>
  </ul>
</div>
<div class="scrollbox">
  <ul>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
  </ul>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related