We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
本文,我们来看这么个有意思的问题。使用 CSS,实现在页面屏幕中有一长串多行字母,现在需要随着页面滚动,改变每个字母的颜色。这也是掘金上一个同学的私信提问:
这里和这位同学细聊,他没有回复,有一个细节我没获取到,就是多行文本一开始是文字颜色是规律的还是不规律的,另外一个点,随着页面滚动,改变每个字母的颜色,需要有规律的改变,还是没有规律的改变?
这问题细琢磨,还是非常有意思的,效果的核心是:
带着这两个疑问,我们尝试使用 CSS 一步一步解决它!
我们先来看,如何使用单个标签实现多行文本下单个文字不同颜色。这是之前在 【动画进阶】单标签下多色块随机文字随机颜色动画 讲解过的一个技巧。
看看如下效果:
停顿 10s,思考一下,如果仅仅使用一个标签,实现上面的效果,这是可能的吗?
这里,我们还可以利用内联元素的 background 展示特性来实现。
background
什么意思呢?其实 background 的展示,在 块级元素状态 和 内联元素状态 下的展示规则是不一样的。
表现为 display: inline 内联元素的 background 展现形式与 display: block 块级元素(或者 inline-block、flex、grid)不一致。
display: inline
display: block
inline-block
flex
grid
简单看个例子:
<p>Lorem .....</p><a>Lorem .....</a>
这里需要注意,<p> 元素是块级元素,而 <a> 是内联元素。
<p>
<a>
我们给它们统一添加上一个从绿色到蓝色的渐变背景色:
p, a { background: linear-gradient(90deg, blue, green); }
看看效果:
什么意思呢?区别很明显:
基于这一点,我们同样可以实现单个 DIV 下的多重背景。
举个例子:
<div class="g-container"> <span>ABCDEFGHIJKL</span> </div>
div { width: 300px; } span{ color: #000; font-size: 50px; line-height: 50px; letter-spacing: 25px; word-wrap: break-word; background: #fc0; }
此时,我们只设置了一个背景 background: #fc0,效果如下:
background: #fc0
基于上面说的技巧,我们改造一下 background: #fc0,拆分成多段渐变背景:
span{ //... background: linear-gradient( 90deg, #fc0 0 25%, #0f0 0 50%, #00f 0 75%, #f00 0 100% ); }
这里,我们每隔 25%,设置了一段不同的颜色,如此一来,整个背景色就变成了 4 块:
基于这个技巧,我们同样可以封装一个 SCSS 函数,用于在单个 DIV 下生成多段色块。代码如下:
@use "sass:string"; @import url('https://fonts.googleapis.com/css2?family=Righteous&family=Ubuntu+Mono&display=swap'); $str: 'QWERTYUIOPASDFGHJKLZXCVBNMabcdefghigklmnopqrstuvwxyz123456789'; $length: str-length($str); @function randomNum($max, $min: 0, $u: 1) { @return ($min + random($max)) * $u; } @function randomColor() { @return rgb(randomNum(205, 50), randomNum(255), randomNum(255)); } @function randomLinear($count, $width) { $value: ''; @for $i from 0 through ($count - 1) { $j: $i - 1; $value: $value + randomColor() + string.unquote(" #{$j * $width}px #{$i * $width}px,"); } @return linear-gradient(90deg, string.unquote(#{$value}) randomColor() 0 100%); } span { background: randomLinear(36, 50); }
上面的代码,我们实现了一个 randomLinear($count, $width) 的 SCSS 函数,其中:
randomLinear($count, $width)
$count
$width
如此一来,在一个 300px x 300px 的内联元素内,我们同样可以实现多个不同的随机颜色。利用这个技巧,一样可以实现单个平面下的随机文字随机颜色效果:
300px x 300px
剩余的技巧都是相同的,这里就不再赘述,此技巧的完整代码,你可以戳这里:CodePen Demo -- Single Div Random Text And Random Color
我们将上述技巧,运用在我们今天需要实现的效果之上。
假设,我们有如下一段多行文本:
<a>Lorem ipsum dolor sit amet consectetur adipisicing elit.?</a>
效果如下:
我们只需要利用 inline display 的特性,利用渐变实现每个文字宽度下,不一样的颜色效果:
inline
给上述效果,添加上 backgroug-clip: text0 和 color: transparent,即可实现单个标签下,多行文本每个文字的颜色都不一样:
backgroug-clip: text0
color: transparent
整个效果的核心,就是如何利用渐变,给每个文字宽度下,设置不一样的颜色。
下面,我们继续实现基于滚动驱动动画,实现滚动下文字变色效果。
当然,这里的滚动动作,只是实现动画效果的载体,其背后的本质还是基于上述效果下的文字变色。
这里也很好实现,我们有两种方式,基于上述效果实现文字变色效果:
filter: hue-rotate()
background-position
两种方式,都可以实现,多行文本下,每个文字的颜色单独变色。
再不加入滚动驱动动画之前,我们首先实现多行文字的颜色变换。
上述效果的完整代码,目前是这样的:
@use "sass:string"; @function randomLinear($count, $width) { $value: ''; @for $i from 0 through ($count - 1) { $j: $i - 1; $value: $value + randomColor() + string.unquote(" #{$j * $width}px #{$i * $width}px,"); } @return linear-gradient(90deg, string.unquote(#{$value}) randomColor() 0 100%); } @function randomColor() { @return rgb(randomNum(205, 50), randomNum(255), randomNum(255)); } @function randomNum($max, $min: 0, $u: 1) { @return ($min + random($max)) * $u; } a { width: 600px; font-size: 42px; line-height: 54px; font-family: "Roboto Mono", monospace; background: randomLinear(72, 25); background-clip: text; color: transparent; }
这里唯一需要花时间理解的是 background: randomLinear(72, 25) 绘制的渐变图案。这里实现了一个 72 段长的渐变效果,每个渐变段的宽度是 25px。
background: randomLinear(72, 25)
25px
解释一下,由于我们单行的宽度是 600px,所以 background: randomLinear(72, 25) 恰好可以实现一个铺满 3 行且每个文字宽度下色块颜色不一致的渐变效果。
600px
接着,我们通过控制 background-position 的变换,实现文字颜色的切换,只需要加入如下的代码:
a { ... animation: colorChange 5s steps(18); } @keyframes colorChange { 0% { background-position: 0 0; } 100% { background-position: -1800px 0; } }
其中 72 * 25 = 1800,所以,我们利用 steps 步骤动画,实现一个渐变色块的位移动画(即 background-position 位移动画),运用到整个效果上,呈现出来的效果就是文字颜色的跳变:
72 * 25 = 1800
steps
有了这一步,接下来,我们只需要把动画效果,改为通过滚动动作控制即可,这里我们需要用到 CSS 最新的规范 -- 滚动驱动动画 -- animation-timeline,关于这个最新规范,你可以看看 XboxYan 老师的这篇文章,进行快速入门:
到这里,假设你对 滚动驱动动画 -- animation-timeline 已经掌握,我们只需要简单的改造上述的代码,给页面提供一个滚动动作,并且将动画关联上即可,修改我们的代码:
<div class="g-scroll"></div> <p><a>Lorem ipsum dolor sit amet consectetur adipisicing elit.?</a></p>
@use "sass:string"; @import url('https://fonts.googleapis.com/css2?family=Carter+One&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Sofia+Sans&display=swap'); @function randomLinear($count, $width) { $value: ''; @for $i from 0 through ($count - 1) { $j: $i - 1; $value: $value + randomColor() + string.unquote(" #{$j * $width}px #{$i * $width}px,"); } @return linear-gradient(90deg, string.unquote(#{$value}) randomColor() 0 100%); } @function randomColor() { @return rgb(randomNum(205, 50), randomNum(255), randomNum(255)); } @function randomNum($max, $min: 0, $u: 1) { @return ($min + random($max)) * $u; } body, html { width: 100%; height: 100%; overflow: scroll; background: #000; scroll-timeline-name: --my-scroller; } .g-scroll { height: 300vh; } p { position: fixed; display: inline; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: auto; width: 600px; } a { width: 600px; font-size: 42px; line-height: 54px; font-family: "Roboto Mono", monospace; color: #fff; background: randomLinear(72, 25); background-clip: text; color: transparent; animation: colorChange steps(18); animation-timeline: --my-scroller; } @keyframes colorChange { 0% { background-position: 0 0; } 100% { background-position: -1800px 0; } }
上面是完整的代码,其实代码量非常少,添加的代码做了几件事:
fixed
300vh
body
scroll-timeline-name: --my-scroller
a
animation-timeline: --my-scroller
这样,我们就实现了,在滚动过程中,改变多行文本的每一个字的颜色,并且,其核心效果,其实都是利用一个标签实现的:
完整的代码,你可以戳这里:CodePen Demo -- Text Color Change With Scroll
当然,如果这样的效果都已经能够掌握了,那么想要实现规则的文字颜色的规则变换,也非常轻松。
我们改造一下代码,这次的渐变色不需要那么复杂:
body, html { width: 100%; height: 100%; overflow: scroll; background: #000; scroll-timeline-name: --my-scroller; } .g-scroll { height: 300vh; } p { position: fixed; display: inline; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: auto; width: 600px; } a { width: 600px; font-size: 42px; line-height: 54px; font-family: "Roboto Mono", monospace; color: #fff; background: linear-gradient(90deg, #fc0 0 1400px, #fff 0 2800px); background-size: 2800px 100%; background-clip: text; color: transparent; animation: colorChange steps(56); animation-timeline: --my-scroller; } @keyframes colorChange { 0% { background-position: -1400px 0; } 100% { background-position: 0 0; } }
由于这里需要精确控制滚动过程中,字体颜色从一个颜色,到滚动到底部变换到另外一个颜色。上面的 background: linear-gradient(90deg, #fc0 0 1400px, #fff 0 2800px)中的1400px和2800px,以及 animation: colorChange steps(56)` 中的 56 步骤,都需要根据实际文字的数量进行计算。(当然实际过程中也需要考虑不同字体带来的单个字的宽度影响,一般使用等宽字体处理)。
中的
和
,以及
这样,我们就可以得到这么一种效果:
多行文本字体颜色,随着滚动过程的规律变换,并且重要的是,这里不需要对每个文字单独使用一个标签!
完整的代码效果,你可以戳这里:CodePen -- Text Color Change With Scroll
好了,本文到此结束,希望本文对你有所帮助 :)
想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻 😄
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
本文,我们来看这么个有意思的问题。使用 CSS,实现在页面屏幕中有一长串多行字母,现在需要随着页面滚动,改变每个字母的颜色。这也是掘金上一个同学的私信提问:
这里和这位同学细聊,他没有回复,有一个细节我没获取到,就是多行文本一开始是文字颜色是规律的还是不规律的,另外一个点,随着页面滚动,改变每个字母的颜色,需要有规律的改变,还是没有规律的改变?
这问题细琢磨,还是非常有意思的,效果的核心是:
带着这两个疑问,我们尝试使用 CSS 一步一步解决它!
单个标签实现多行文本下单个文字不同颜色
我们先来看,如何使用单个标签实现多行文本下单个文字不同颜色。这是之前在 【动画进阶】单标签下多色块随机文字随机颜色动画 讲解过的一个技巧。
看看如下效果:
停顿 10s,思考一下,如果仅仅使用一个标签,实现上面的效果,这是可能的吗?
这里,我们还可以利用内联元素的
background
展示特性来实现。什么意思呢?其实
background
的展示,在 块级元素状态 和 内联元素状态 下的展示规则是不一样的。表现为
display: inline
内联元素的background
展现形式与display: block
块级元素(或者inline-block
、flex
、grid
)不一致。简单看个例子:
这里需要注意,
<p>
元素是块级元素,而<a>
是内联元素。我们给它们统一添加上一个从绿色到蓝色的渐变背景色:
看看效果:
什么意思呢?区别很明显:
基于这一点,我们同样可以实现单个 DIV 下的多重背景。
举个例子:
此时,我们只设置了一个背景
background: #fc0
,效果如下:基于上面说的技巧,我们改造一下
background: #fc0
,拆分成多段渐变背景:这里,我们每隔 25%,设置了一段不同的颜色,如此一来,整个背景色就变成了 4 块:
基于这个技巧,我们同样可以封装一个 SCSS 函数,用于在单个 DIV 下生成多段色块。代码如下:
上面的代码,我们实现了一个
randomLinear($count, $width)
的 SCSS 函数,其中:$count
表示需要的色块个数$width
表示每个色块的宽度如此一来,在一个
300px x 300px
的内联元素内,我们同样可以实现多个不同的随机颜色。利用这个技巧,一样可以实现单个平面下的随机文字随机颜色效果:剩余的技巧都是相同的,这里就不再赘述,此技巧的完整代码,你可以戳这里:CodePen Demo -- Single Div Random Text And Random Color
我们将上述技巧,运用在我们今天需要实现的效果之上。
假设,我们有如下一段多行文本:
效果如下:
我们只需要利用
inline
display 的特性,利用渐变实现每个文字宽度下,不一样的颜色效果:给上述效果,添加上
backgroug-clip: text0
和color: transparent
,即可实现单个标签下,多行文本每个文字的颜色都不一样:整个效果的核心,就是如何利用渐变,给每个文字宽度下,设置不一样的颜色。
基于滚动驱动动画,实现滚动下文字变色效果
下面,我们继续实现基于滚动驱动动画,实现滚动下文字变色效果。
当然,这里的滚动动作,只是实现动画效果的载体,其背后的本质还是基于上述效果下的文字变色。
这里也很好实现,我们有两种方式,基于上述效果实现文字变色效果:
filter: hue-rotate()
动画,实现文字变色background-position
的位移动画,实现文字变色效果两种方式,都可以实现,多行文本下,每个文字的颜色单独变色。
再不加入滚动驱动动画之前,我们首先实现多行文字的颜色变换。
上述效果的完整代码,目前是这样的:
这里唯一需要花时间理解的是
background: randomLinear(72, 25)
绘制的渐变图案。这里实现了一个 72 段长的渐变效果,每个渐变段的宽度是25px
。解释一下,由于我们单行的宽度是
600px
,所以background: randomLinear(72, 25)
恰好可以实现一个铺满 3 行且每个文字宽度下色块颜色不一致的渐变效果。接着,我们通过控制
background-position
的变换,实现文字颜色的切换,只需要加入如下的代码:其中
72 * 25 = 1800
,所以,我们利用steps
步骤动画,实现一个渐变色块的位移动画(即background-position
位移动画),运用到整个效果上,呈现出来的效果就是文字颜色的跳变:有了这一步,接下来,我们只需要把动画效果,改为通过滚动动作控制即可,这里我们需要用到 CSS 最新的规范 -- 滚动驱动动画 -- animation-timeline,关于这个最新规范,你可以看看 XboxYan 老师的这篇文章,进行快速入门:
到这里,假设你对 滚动驱动动画 -- animation-timeline 已经掌握,我们只需要简单的改造上述的代码,给页面提供一个滚动动作,并且将动画关联上即可,修改我们的代码:
上面是完整的代码,其实代码量非常少,添加的代码做了几件事:
fixed
定位到页面中心300vh
高的容器,利用这个容器,触发 body 的滚动效果,并且给body
设置了滚动容器 namescroll-timeline-name: --my-scroller
a
标签下的动画,改成关联页面的滚动动作animation-timeline: --my-scroller
这样,我们就实现了,在滚动过程中,改变多行文本的每一个字的颜色,并且,其核心效果,其实都是利用一个标签实现的:
完整的代码,你可以戳这里:CodePen Demo -- Text Color Change With Scroll
当然,如果这样的效果都已经能够掌握了,那么想要实现规则的文字颜色的规则变换,也非常轻松。
我们改造一下代码,这次的渐变色不需要那么复杂:
由于这里需要精确控制滚动过程中,字体颜色从一个颜色,到滚动到底部变换到另外一个颜色。上面的 background: linear-gradient(90deg, #fc0 0 1400px, #fff 0 2800px)
中的
1400px和
2800px,以及
animation: colorChange steps(56)` 中的 56 步骤,都需要根据实际文字的数量进行计算。(当然实际过程中也需要考虑不同字体带来的单个字的宽度影响,一般使用等宽字体处理)。这样,我们就可以得到这么一种效果:
多行文本字体颜色,随着滚动过程的规律变换,并且重要的是,这里不需要对每个文字单独使用一个标签!
完整的代码效果,你可以戳这里:CodePen -- Text Color Change With Scroll
最后
好了,本文到此结束,希望本文对你有所帮助 :)
想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻 😄
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
The text was updated successfully, but these errors were encountered: