CSS数学函数与容器查询实现不定宽文本溢出跑马灯效果

分类:知识百科 日期: 点击:0

很久以前,我写过这样一篇文章 -- 不定宽溢出文本适合滚动。我们已经达到了这样的效果:

  1. 文本内容不超过容器宽度,正常显示
  2. 如果文本内容超过容器,内容可以来回滚动

像是这样:

然而,以前的计划有一个明显的缺点,如果我们事先知道容器的宽度,那么没有问题,但如果不能确定容器的宽度,文本宽度不确定,容器宽度不确定,那么整个效果就会有一点缺陷

瑕疵在于,当时的 CSS 事实上,技术无法判断当前文本内容的长度是否超过其容器宽度,即使文本没有超长,Hover 上去也会来回滚动,就像这样:

容器查询 cqw 和 CSS 数学函数 max

背景描述可能是这样的。感兴趣的学生可以简单地阅读上午提到的文章 -- 不定宽溢出文本适用于滚动。

今天,我们将重新审视这个问题。看看今天,我们如何更简单、更方便地解决这个问题!

我们的问题可以抽象成:

  1. 判断文本宽度与容器宽度的差异,文本宽度是否大于容器宽度
  2. 如果超过,则设置来回位移动画。位移的范围是容器宽度与文本宽度之间的差异

我们一步一步来。

假设我们的 HTML 结构如下:

Lorem ipsum dolor sit amet elit. Animi, aliquid.

其中,div 为容器,span 文本内容。同时,我们使用容器查询设置父容器 marquee 为容器查询容器,并将基于容器inline-size 维度。

.marquee {
	white-space: nowrap;
	container-type: inline-size;
}

继续,我们怎么能继续呢? span 中学知道, span 谁更大的内容长度和父容器宽度?

以前很难做到,但我们有了 容器查询 之后,可以依靠容器查询单位 cqw 完成。

什么是容器查询?容器查询它给予了 CSS,在不改变浏览器视口宽度的前提下,只能根据容器宽度的变化来调整布局。

想了解更多关于容器查询的信息,可以戳:新时代布局新特点 -- 容器查询

容器查询带来了许多新的单位,包括:

  • cqw 容器查询宽度(Container Query Width)比例。1cqw 等于容器宽度 假设容器宽度是1%。 此时1000px, 1cqw 相应的计算值是 10px。
  • cqh 容器查询高度(Container Query Height)比例。1cqh 等于容器的高度 1%。
  • cqi 表示容器查询内联方向的尺寸(Container Query Inline-Size)比例。这是一个逻辑属性单位,在默认情况下相当于 cqw
  • cqb 容器查询块级方向尺寸(Container Query Block-Size)比例。同上,在默认情况下相当于 cqh
  • cqmin 小尺寸的容器查询(Container Query Min)占比。取 cqw 和 cqh 中小一个
  • cqmax 表示容器查询尺寸较大的容器(Container Query Min)占比。取 cqw 和 cqh 较大的一个
  • 本文将应用于其中 cqw,1cqw 等于容器宽度 1%。当前容器的宽度实际上是 100 cqw。

    那么:

    1. width: 100% ,对于 span 就行业元素而言,其文本长度是其整体宽度,100% 代表文本内容的长度
    2. width: 100cqw 这意味着设置了容器查询 .marquee 宽度(即父容器的宽度)

    OK,有了 100%100cqw 谁大谁小怎么比较?其实我们的关键不是谁大谁小,而是:

    1. 如果当前容器的宽度(即文本宽度)大于父容器的宽度,则需要获得动画位置值
    2. 如果当前容器的宽度(即文本宽度)小于父容器的宽度,则不需要动画,即动画的位移值 0

    我们的核心变成了,0 对比两个宽度差值。正好,CSS 它提供了一个相对大小的数学函数 max()min()

    关于 CSS 数学函数,你可以参考我的文章 -- 现代 CSS 解决方案:CSS 数学函数

    经过这么长时间的铺垫,我们终于得到了核心代码:

    max(100% - 100cqw, 0px)
    

    当然,用另一种思维, min() 也可以:

    min(100cqw - 100%, 0px)
    

    如果 span 内容长度大于容器宽度,即 100% - 100cqw 大于 0px,事实上,跑马灯效果应该位移的距离已经得到了。

    顺便说一句,我们已经完成了整个效果的代码,完整的代码:

    .marquee {
    	overflow: hidden;
    	white-space: nowrap;
    	width: 200px;
    	resize: horizontal;
    	container-type: inline-size;
    }
    .marquee span {
          animation: marquee 3s linear infinite both alternate;
    }
    @keyframes marquee {
    	to {
    		transform: translateX(min(100cqw - 100%, 0px));
    	}
    }
    

    效果如下:

    这样,我们就可以很容易地实现今天:

    1. 文本内容不超过容器宽度,正常显示
    2. 如果文本内容超过容器,内容可以来回滚动

    即以下效果:

    您可以在这里戳到完整的代码:Pure CSS Marquee

    当然,如果很难说,这个方案仍然存在一个缺陷,即动画的长度是固定的,不能根据内容的长度进行适应。它可能更适合文本内容相差不大的场景。


    标签:

    版权声明

    1. 本站所有素材,仅限学习交流,仅展示部分内容,如需查看完整内容,请下载原文件。
    2. 会员在本站下载的所有素材,只拥有使用权,著作权归原作者所有。
    3. 所有素材,未经合法授权,请勿用于商业用途,会员不得以任何形式发布、传播、复制、转售该素材,否则一律封号处理。
    4. 如果素材损害你的权益请联系客服QQ:77594475 处理。