[我从2012年发现this infamous article。它详细说明了如何创建滚动阴影,并且效果仍然不错,但是我真的很想了解该解决方案,而且似乎无法在线找到必要的信息。
这里是@kizmarh最初创建(blog-post)并由@leaverou改进的最小代码:
.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;
不能使用?白色阴影如何覆盖黑色阴影,同时使其后面的内容保持可见?
内容不在它们后面,内容在上面是合乎逻辑的,因为内容总是在背景之上。在阴影上使用黑色着色与文字着色相同,使您认为阴影在上方,但不是。
如何通过在声明之后放置百分比来放置渐变(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% 0
(left 50% top 0
或center 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;
}
<div class="box"></div>
我们的背景大小为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;
}
<div class="box"></div>
使用具有不同值的代码可以更好地看到:
.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
)简化为仅top
,并且对于center bottom
同样如此
一些相关问题,以获取有关radial-gradient
的更多详细信息:
How to animate a radial-gradient using CSS?
How to control height of ellipse in radial gradient
为什么没有背景颜色就无法使用:白色;?
没有以下内容也可以正常工作:
.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>