【问题标题】:How does this scrolling shadows CSS-magic work?这个滚动阴影 CSS-magic 是如何工作的?
【发布时间】:2020-04-13 05:04:21
【问题描述】:

我从 2012 年找到了 this infamous article。它详细说明了如何创建滚动阴影并且仍然可以很好地工作,但我真的很想了解解决方案,但我似乎无法在网上找到必要的信息。

这是最初由@kizmarh 创建并由@leaverou 改进的缩小代码(blog-post):

.scrollbox {
  overflow: auto;
  width: 200px;
  max-height: 150px;
  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;
  background-attachment: local, local, scroll, scroll;
}
<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>

如果有人能解释一下这种效果是如何实现的?我想我得到了一般要点(如果无法通过背景附件实现进一步滚动,则有白色阴影覆盖黑色阴影),但我真的对以下一些事情感到困惑:

  • 白色阴影如何覆盖黑色阴影,而其后面的内容仍然可见?
  • 如何通过在声明后放置百分比来放置渐变 (linear-gradient(...) n% n%)?
  • 为什么使用后台速记时代码不起作用?
  • farthest-side at 50% 0 到底在做什么?
  • 为什么没有background-color: white; 就不行?

【问题讨论】:

    标签: css background-image background-color linear-gradients radial-gradients


    【解决方案1】:

    白色阴影如何遮盖黑色阴影,而它们后面的内容仍然可见?

    内容不在它们后面,内容在上面,这是合乎逻辑的,因为内容总是在背景之上。在阴影上使用黑色与文字着色相同,让您认为阴影在上方,但实际上并非如此。

    如何通过在声明后放置百分比来放置渐变 (linear-gradient(...) n% n%)?

    0% 100% 表示left 0% top 100%left bottom 相同,并且由于背景的宽度等于100%(使用background-size 设置)它也与bottom 相同(与完整相关详情:Using percentage values with background-position on a linear-gradient)

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      background: 
        /* Shadow covers */
        linear-gradient(white 30%, transparent), 
        linear-gradient(transparent, white 70%) bottom,
    
        /* 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)) bottom;
      background-repeat: no-repeat;
      background-color: white;
      background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
      background-attachment: local, local, scroll, scroll;
    }
    <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>

    为什么使用后台速记时代码不起作用?

    你只需要像下面这样正确地写它:

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      background: 
        /*Gradient                            position / size  repeat attachment*/
      
        /* Shadow covers */
        linear-gradient(white 30%, transparent) top   /100% 40px no-repeat local, 
        linear-gradient(transparent, white 70%) bottom/100% 40px no-repeat local,
    
        /* Shadows */
        radial-gradient(farthest-side at 50% 0   , rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) top   /100% 14px no-repeat, 
        radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) bottom/100% 14px no-repeat,
        #fff;
    }
    <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>

    请注意我是如何删除 scroll 的,因为它是默认值,您需要为所有渐变指定位置,因为它是必需的,简写为 background-size(相关 Issues with "background-position" in "background" shorthand property)。

    50% 0 的最远侧到底在做什么?

    它正在创建一个结束形状,其中心位于50% 0left 50% top 0center top),它应该接触到由background-size 定义的背景区域的边缘。对于50% 100%,它是center bottom

    下面是一个基本的例子来说明:

    .box {
      width:200px;
      height:100px;
      background:
        radial-gradient(farthest-side at center top,red 100%,transparent 100%) top/100% 50px no-repeat;
      border:1px solid;
    }
    &lt;div class="box"&gt;&lt;/div&gt;

    我们的背景大小是100% 50px,红色曲率接触边缘,因为色标是100%,创建了我们的半椭圆。

    另一个简单的例子,我们将形状的中心保持在中心:

    .box {
      width:200px;
      height:100px;
      background:
        radial-gradient(farthest-side,red 100%,transparent 100%) top/100% 50px no-repeat;
      border:1px solid;
    }
    &lt;div class="box"&gt;&lt;/div&gt;

    使用我们的代码以不同的值更好地查看:

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      background: 
        /* Shadow covers */
        linear-gradient(white 30%, transparent) top   /100% 40px no-repeat local, 
        linear-gradient(transparent, white 70%) bottom/100% 40px no-repeat local,
    
        /* Shadows */
        radial-gradient(farthest-side at top    , red 100%, rgba(0, 0, 0, 0)) top   /100% 14px no-repeat, 
        radial-gradient(farthest-side at bottom , red 100%, rgba(0, 0, 0, 0)) bottom/100% 14px no-repeat,
        #fff;
    }
    <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>

    注意我是如何将center top (50% 0) 简化为仅topcenter bottom 相同的

    一些相关问题以获取有关radial-gradient 的更多详细信息:

    How to animate a radial-gradient using CSS?

    How to control height of ellipse in radial gradient

    为什么不使用 background-color: white;?

    没有:

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      background: 
        /* Shadow covers */
        linear-gradient(white 30%, transparent) top   /100% 40px no-repeat local, 
        linear-gradient(transparent, white 70%) bottom/100% 40px no-repeat local,
    
        /* Shadows */
        radial-gradient(farthest-side at top , rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) top/100% 14px no-repeat, 
        radial-gradient(farthest-side at bottom , rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) bottom/100% 14px no-repeat;
    }
    <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>

    这里是使用不同颜色和值的代码,以更好地理解每个渐变和正在发生的事情。您还可以清楚地注意到文字在上面,不需要白色背景。

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      font-weight:bold;
      font-size:25px;
      background: 
        /* Shadow covers */
        linear-gradient(red 30%, white) top       /100% 40px no-repeat local, 
        linear-gradient(white, red 70%) bottom/100% 40px no-repeat local,
    
        /* Shadows */
        radial-gradient(farthest-side at top , yellow 100%, green 100%) top/100% 30px no-repeat, 
        radial-gradient(farthest-side at bottom , yellow 100%, green 100%) bottom/100% 30px no-repeat;
    }
    
    body {
     background:pink;
    }
    ul {
      margin:0;
      padding:0;
    }
    <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>

    这是您的初始代码的优化版本:

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      background: 
        linear-gradient(white 30%, transparent), 
        radial-gradient(farthest-side at top, rgba(0, 0, 0, .2), transparent),
        
        linear-gradient(transparent, white 70%) bottom,
        radial-gradient(farthest-side at bottom, rgba(0, 0, 0, .2), transparent) bottom;
      background-repeat: no-repeat;
      background-size: 100% 40px,100% 14px;
      background-attachment: local, scroll;
    }
    <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>

    另一个版本:

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      
      --rad:radial-gradient(farthest-side, rgba(0, 0, 0, .2), transparent);  
      background: 
        linear-gradient(white 30%, transparent), 
        var(--rad) 0 -14px,
        
        linear-gradient(transparent, white 70%) bottom,
        rvar(--rad) 0 calc(100% + 14px);
      background-size: 100% 40px,100% 28px;
      background-attachment: local, scroll;
      background-repeat: no-repeat;
    }
    <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>

    还有一个梯度较小的:

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      
      --rad:radial-gradient(50% 50%, rgba(0, 0, 0, .2), transparent) no-repeat;  
      background: 
        linear-gradient(white 12px, transparent 40px calc(100% - 40px),white calc(100% - 12px)) local, 
        var(--rad) left 0 top    -14px / 100% 28px,    
        var(--rad) left 0 bottom -14px / 100% 28px;
      
    }
    <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>

    最后一个(是的最后一个..)代码更少:

    .scrollbox {
      overflow: auto;
      width: 200px;
      max-height: 150px;
      
      --rad:radial-gradient(50% 14px, rgba(0, 0, 0, .2), transparent);  
      background: 
        linear-gradient(white 12px, transparent 40px calc(100% - 40px),white calc(100% - 12px)) local, 
        var(--rad) top   /100% 200%,    
        var(--rad) bottom/100% 200%;
      
    }
    <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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-22
      • 2013-02-25
      相关资源
      最近更新 更多