当前位置: 首页 > 科技观察

CSS 实现自适应文本的头像

时间:2023-03-14 20:55:28 科技观察

Ant-design中有这样一个头像组件,当字符串较长时,可以根据头像的宽度自动调整字体大小,效果如下:当然这里是根据字符数自动调整通过JSScaledtext实现。现在,只需要通过CSS就可以实现类似的效果,如下:一起来看看吧!1.CSS容器尺寸单位要实现这个效果,就需要用到容器尺寸单位。这些单元与CSS容器查询[1]一起出现,如下所示。容器查询可以参考这篇文章:介绍2022年最值得期待和官方支持的CSS容器查询?张新旭-新空间-新生活(zhangxinxu.com)[2],本文不涉及具体的容器查询语句.cqw容器查询宽度(ContainerQueryWidth)的比例。1cqw等于容器宽度的1%。假设容器宽度为1000px,那么1cqw对应的计算值为10px。cqh容器查询高度(ContainerQueryHeight)的比例。1cqh等于容器高度的1%。cqi表示容器查询内联大小(ContainerQueryInline-Size)的比例。这是逻辑属性单元,默认相当于cqwcqb容器查询块级方向大小(ContainerQueryBlock-Size)的比例。同上,默认情况下等同于cqh。.cqmin容器查询较小尺寸(ContainerQueryMin)的比率。取cqw和cqh中较小的一个。cqmax表示较大的容器查询大小(ContainerQueryMin)的比例。取cqw和cqh中的较大者。有了这些尺寸单位,就很容易意识到文字的尺寸会随着容器的尺寸而变化。下面是一个例子:大家好,欢迎来到前端神探

在没有声明容器类型的情况下,cqw相当于vw,也就是相当于把整个页面当做一个容器。这里,我们希望使用这个div作为引用对象,需要提前声明container-type,如下:.con{container-type:inline-size;}.text{font-size:10cqw;}效果如下:这样就轻松实现了文字缩放效果。原理很简单,如何应用呢?2.自适应文字头像回过头来看实际案例,如何让字体大小根据头像的宽度自适应呢?也就是说,文字越多,字体越小。一个比较简单的思路就是文字越多占的宽度越大,然后根据前面的原则,让文字大小随着宽度变化,但是这里是成反比的,宽度越宽,字体越小.假设HTML是这样的。侦探
简单修改:.avator{display:flex;对齐项目:居中;证明内容:居中;宽度:40px;高度:40px;边界半径:8px;背景:素瓷;颜色:RGB(250、84、28);white-space:nowrap;}效果如下:现在问题来了,目前外宽是固定的,好像没办法根据文字调整就占宽,查询一下容器,what我应该怎么做?我的想法是创建一个相同的文本,让外部容器(A)的宽度由内部文本确定,然后将容器框(B)的宽度设置为与(A)的宽度相同,所以那容器没有完成查询?按照这个思路,HTML可以改成这样:Detective
外层容器A的文本可以通过伪元素生成:.avator-inner::before{内容:attr(alt);font-size:40px;}这时候外层容器A,也就是.avator-inner的大小被伪元素::before完全展开了,如下:那么,容器BoxB,也就是,.avator-container设置为和外层容器A一样,可以使用绝对定位。.avator-container{位置:绝对;插图:0;容器类型:内联大小;文本对齐:居中;显示:弹性;证明内容:居中;align-items:center;}这样,容器框可以跟随伪元素的大小自动变化,然后为内部文本设置合适的大小。由于成反比,所以可以相减,如下:.avator-containerspan{font-size:calc(24px-10cqw);}效果如下:再次改变文字,比如4个字符;可以看出,文字越多,内部文字尺寸越小,这正是我们需要的效果。接下来隐藏伪元素生成的文字,就可以得到文章开头的效果,如下:需要注意的是,因为是通过font-size实现的,所以需要最小字号限制在浏览器中解除。这是完整的代码:.avator{display:flex;对齐项目:居中;证明内容:居中;宽度:40px;高度:40px;边界半径:8px;背景:素瓷;颜色:RGB(250、84、28);空白:nowrap;}.avator-inner{位置:相对;}.avator-inner::before{内容:attr(alt);可见性:隐藏;font-size:40px;}.avator-container{position:absolute;插图:0;容器类型:内联大小;文本对齐:居中;显示:弹性;证明内容:居中;align-items:center;}.avator-containerspan{字体大小:calc(24px-10cqw);溢出:隐藏;最大宽度:40px;text-overflow:ellipsis;}您也可以访问在线演示:CSSavator(codepen.io)[3]或CSSavator(runjs.work)[4]。3、容器查询的一些局限性虽然之前也实现过这样的效果,但是不是很优雅,主要是容器查询有很多局限性。1、首先,容器查询只对容器的子元素有效,对自身无效,这就导致了一些冗余结构。上面的例子中,div容器中还包含了一个p元素,在p元素上设置了文字大小,显得有些多余。可以直接在div上设置吗?这样就省去了一层标签。答案是不!下面是直接在div上设置的效果。如您所见,文本大小取决于页面视图宽度。所以,如果直接设置在div上,那么此时cqw所引用的容器就不再是自己了,而是继续向上查找,直到最外层,也就是说cqw查找的对象是最近的父容器元素,并且不包含自身,这个需要多多注意。2.另外,容器查询框本身的大小不能由内部元素决定。这就是在上面的示例中创建相同文本的原因。例如,如果不设置容器框本身的宽度,那么正常的inline-block元素的宽度应该由内部文本决定,但是设置了container-type之后就不行了,没有根本没有宽度,这就是为什么必须通过绝对定位直接设置宽度的原因。不过道理也很好理解:假设这是真的,如果子元素的字体大小发生变化,那么容器宽度也会发生变化,而容器宽度又会导致字体大小发生变化。这是一个无限循环,所以这是不允许的。3、最后,容器查询尺寸对应的具体尺寸是一个尺寸单位,这就导致很多属性无法应用,比如scale。在上面的示例中,文本大小由font-size更改。其实最好的办法就是scale,因为浏览器有最小字号限制,而scale没有这个限制,但是单位cqw不能用在scale上面,有点遗憾,如果有就好了是百分比单位。当然,如果不嫌麻烦的话,可以使用@container进行精确控制。4.总结以上就是本文的全部内容。主要是利用容器大小单位来实现自适应文字大小的效果,总结了目前一些容器查询的局限性。下面总结一下:containersizeunit跟随CSScontainer查询一起出现的新单位,包括cqw、cqh、cqi、cqb、cqmin、cqmax。容器大小单位需要在声明容器类型的框中有效,否则整个页面会被视为一个容器,相当于vw和vh。由于头像的宽度是固定的,不能直接根据文本宽度容器查询。需要创建相同文本的副本来创建容器查询条件。头像上的文字越多,字体越小,所以成反比,可以用减法的方法。实现起来不是很优雅,HTML结构比较多,主要是容器查询限制比较多。容器查询只对容器的子元素有效,对自身无效,这就导致了一些冗余结构。容器查询框本身的大小无法由内部元素决定,会导致死循环。容器查询大小对应的具体大小不支持百分比等相对单位。然而,尽管有很多限制,容器查询仍然是目前最有价值的新特性之一。很多以前需要用到的技巧和窍门可以用新的方式实现,后面会分享。