欢送关注我的公众号:前端侦探

Ant-design 中有一个这样的头像组件,当字符串较长时,字体大小能够依据头像宽度主动调整,成果如下

当然,这里是通过JS依据字符数量主动缩放文本实现的

而当初,仅仅通过 CSS也能达到相似的成果,一起看看吧

你也能够提前拜访线上 demo: CSS avator (runjs.work)

一、CSS 容器尺寸单位

实现这个成果须要借助容器尺寸单位。这些单位是追随CSS容器查问一起呈现的,有以下几种

对于容器查问,能够参考这篇文章:介绍2022最期待且已正式反对的CSS container容器查问 « 张鑫旭-鑫空间-鑫生存 (zhangxinxu.com),本文并不波及具体容器查问语句
  • 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)占比。取 cqwcqh较小的一个
  • cqmax 示意容器查问较大尺寸的(Container Query Min)占比。取 cqwcqh较大的一个

有了这些尺寸单位,能够很轻易的实现文字大小随着容器尺寸的变动而变动,上面举个例子

<div class="con">  <p class="text">大家好,欢送关注前端侦探</p></div>

在不申明容器类型的状况下,cqw等同于vw,也就是相当于把整个页面当成容器,这里心愿将这个div作为参考对象,须要提前申明container-type,如下

.con {    container-type: inline-size;}.text{  font-size: 10cqw;}

成果如下

这样就很轻易的实现了文本缩放成果。

原理很简略,怎么利用呢?

二、自适应文本头像

再回过头来看看理论案例,如何让字体大小依据头像宽度自适应呢?也就是文字越多,字号越小。

有一个比较简单的思路就是,文字越多,占据的宽度越多,而后依据后面的原理,让文字大小随着宽度的变动而变动,只不过这里是成反比,宽度越宽,字号越小。

假如HTML是这样的

<div class="avator">    <span>侦探</span></div>

简略润饰一下

.avator{  display: flex;  align-items: center;  justify-content: center;  width: 40px;  height: 40px;  border-radius: 8px;  background: bisque;  color: rgb(250, 84, 28);  white-space: nowrap;}

成果如下

当初问题来了,目前外层宽度是固定的,如同没方法依据文字占据宽度就行容器查问,怎么办呢?

我的思路是这样的,创立一份截然不同的文本,让外层容器(A)宽度由外部文本决定,而后将容器盒子(B)的宽度设置成和(A)一样,这样不就实现了容器查问吗?

依据这个思路,能够将HTML革新成这样

<div class="avator">  <div class="avator-inner" alt="侦探"><!--外层容器A-->    <div class="avator-container"><!--容器盒子B-->      <span>侦探</span>    </div>  </div></div>

外层容器 A 的文本能够通过伪元素生成

.avator-inner::before{  content: attr(alt);  font-size: 40px;}

这时外层容器 A ,也就是.avator-inner的尺寸齐全由伪元素::before撑开,如下

而后,将容器盒子B,也就是.avator-container设置成和外层容器 A 一样,能够采纳相对定位的形式

.avator-container {  position: absolute;  inset: 0;  container-type: inline-size;  text-align: center;  display: flex;  justify-content: center;  align-items: center;}

这样,容器盒子就能够追随伪元素所占大小主动变动了,而后给外部文字设置一个适合的大小,因为是成反比,所以能够采取相减的形式,如下

.avator-container span {  font-size: calc( 24px - 10cqw );}

成果如下

再换一下文本,比方4个字的

能够看到,文本越多,外部文字大小越小,正好是咱们须要的成果

上面把伪元素生成的文本暗藏起来,就能够失去文章结尾的成果了,如下

上面是残缺代码

.avator{  display: flex;  align-items: center;  justify-content: center;  width: 40px;  height: 40px;  border-radius: 8px;  background: bisque;  color: rgb(250, 84, 28);  white-space: nowrap;}.avator-inner{  position: relative;}.avator-inner::before{  content: attr(alt);  visibility: hidden;  font-size: 40px;}.avator-container {  position: absolute;  inset: 0;  container-type: inline-size;  text-align: center;  display: flex;  justify-content: center;  align-items: center;}.avator-container span {  font-size: calc( 24px - 10cqw );  overflow: hidden;  max-width: 40px;  text-overflow: ellipsis;}

你也能够拜访线上 demo: CSS avator (runjs.work)

三、容器查问的一些局限性

尽管后面实现这样的成果,然而还不是很优雅,次要是因为容器查问有诸多的限度

1. 首先,容器查问只对容器的子元素无效,对自身有效,这样导致构造有些冗余

在下面的例子中,div容器中还蕴含了一个p元素,文字大小是设置在p元素上,看似有些多余,能不能间接设置在div上呢?这样就能够省一层标签了。答案是不能够!上面是间接设置在div上的成果

能够看到,文字大小依赖于页面视图宽度了。所以,如果间接设置在div上,那么此时cqw参考的容器就不再是自身了,而是持续向上查找,直到最外层,也就是说cqw查找的对象是最近的父级容器元素,并不蕴含本身,这个须要多多留神

2. 再者,容器查问盒子尺寸自身不能由外部元素所决定

下面的例子中为啥要创立一份雷同的文本呢,起因就是这个,比方在容器盒子自身不设置宽度的状况下,失常的inline-block元素宽度应该是有外部文本决定的,然而设置container-type之后就不行了,齐全没有宽度了,这也就是为啥后面要通过相对定位的形式间接设置宽度了

不过这个起因也容易了解:假如这个成立,如果子元素字号发生变化,导致容器宽度发生变化,容器宽度发生变化又会导致字号发生变化,这样就死循环了,所以不容许这种状况

3. 最初,容器查问尺寸对应的具体的尺寸,是一种尺寸单位,这样导致有很多属性无奈利用,比方scale

在下面的例子中,文字大小是通过font-size扭转的,其实最好的形式是scale,因为浏览器有最小字号的限度,而scale就没这个限度了,然而cqw这种单位无奈用在scale之上,稍微遗憾,如果有一种百分比单位就好了

当然,不嫌麻烦的能够用@container进行精准管制

四、总结一下

以上就是本文全部内容了,次要是利用容器尺寸单位实现了一个自适应文本大小的成果,以及总结了一些容器查问目前的一些局限性,上面总结一下

  1. 容器尺寸单位是追随CSS容器查问一起呈现的新单位,有 cqw、cqh、cqi、cqb、cqmin、cqmax
  2. 容器尺寸单位须要在申明容器类型的盒子内才无效,不然会把整个页面当成容器,等同于 vw、vh
  3. 因为头像宽度是固定的,无奈间接依据文字宽度容器查问,须要创立一份雷同的文原本创立容器查问条件
  4. 头像文字越多,字号越小,所以是成反比,能够采纳相减的形式
  5. 实现还不是很优雅,HTML构造比拟多,次要是因为容器查问有诸多的限度
  6. 容器查问只对容器的子元素无效,对自身有效,这样导致构造有些冗余
  7. 容器查问盒子尺寸自身不能由外部元素所决定,会导致死循环
  8. 容器查问尺寸对应的具体的尺寸,不反对绝对单位,比方百分比

不过,只管有诸多限度,容器查问依然是目前最具价值的新个性之一了,以前很多须要用到的奇技淫巧都能够用新的形式来实现了,这个前面再分享。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

欢送关注我的公众号:前端侦探