10

CSS 实现头像名称首字符自动占位

 1 year ago
source link: https://www.fly63.com/article/detial/11451
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

更新日期: 2022-05-13阅读量: 25标签: 字符分享

扫一扫分享

在 web 中经常会见到这样的设计,很多 UI 组件库也称之为 Avator 组件,也就是头像的意思,当头像未设置时,会显示名称的首字符充当默认头像,如下所示:

62748948a43b8.jpg

那么如何通过 css 实现这一效果呢?

一、图片加载失败时的占位

现代浏览器(Chrome、Firefox) img 标签都支持伪元素了,不过只有当图片加载失败的时候才能看到。

<img class="avator" src="https://tva1.sinaimg.cn/large/008i3skNgy1grgo8qjty1j30e80e8aad.jpg">
<img class="avator" src="">
.avator::before{
  content: '我是伪元素';
  color: red;
}

有了伪元素,要做一些事情就很方便了,比如将默认的“占位图”挤出去,设置伪元素高度为100%就行了,同时设置超出隐藏。

.avator{
  width: 40px;
  height: 40px;
  overflow: hidden; /*记得超出隐藏*/
}
.avator::before{
  content: '';
  display: flex;
  background: bisque;
  height: 100%;
}

二、alt 首字符占位

一般在使用 img 标签时都推荐加上 alt 属性,用来描述图片信息,也非常符合语义化。

<img class="avator" src="" alt="xboxyan">

然后在图片加载失败时,可以通过 attr获取到完整的 alt 信息。

.avator::before{
  content: attr(alt); /* 获取 alt 属性 */
  color: rgb(250, 84, 28);
}

为了方便演示,这里暂时把超出隐藏打开。

那么,如何只显示第一个字符呢?

尝试了一下::first-letter,发现不起作用,伪元素里面不能再用伪元素了;

.avator::before::first-letter{
  /*无效*/
}

需要换一种思路,比如增加字符间距,让其余字符都处于容器之外;

.avator::before{
  /**/
  letter-spacing: 40px;
}

这样一来,首字符“x”确实处于视线之中了。

不过新问题也来了,如何让首字符水平垂直居中呢?

三、首字符水平垂直居中

垂直居中比较好办。设置行高就行了。

.avator::before{
  /**/
  line-height: 40px;
}

水平居中貌似有些棘手,不过发挥你的奇思妙想,问题还是可以解决的!

首先,由于宽度限制,可以把所有的字符强制换行,保证每个字符都处于单独一行,首行也不另外。

.avator::before{
  /**/
  word-break: break-all; /*换行*/
}

前面我们加了一个字符间距,但是字符间距是跟随在字符后面的,所以第一个字符的前面是没有间距的。为了保持首行左右平衡,所以手动加上同样的间距,这里采用text-indent来实现。

.avator::before{
  /**/
 text-indent: 40px; /*首行缩进*/
}

这样对于首行来说,其实是左右边距是一样的。接下来,通过 flex 布局居中就可以了。

.avator::before{
  /**/
  display: flex;
  justify-content: center; /*水平居中*/
}

对于英文字母来说,可能需要转成大写;

.avator::before{
  /**/
  text-transform: capitalize; /*首字母大写*/
}

然后超出隐藏看看效果吧!

四、特殊符号的影响

后来测试中,发现了另外一个问题,当 alt 中有一些特殊标点符号时,首字符会消失不见。

<img class="avator" src="" alt="xboxyan(测试)">

打开隐藏其实是这样的:

627489583f27d.jpg

是不是看着一团糟?其实就是一些闭尾标点惹的祸!比如这里的(,默认情况下是不允许出现在一行的末尾的,所以强制换到了下一行,导致整个布局错乱。为了解决这个问题,可以使用一个比较冷门的 CSS 属性 line-break - CSS(层叠样式表) | MDN (mozilla.org)来解决,有兴趣的可以参考张鑫旭的这篇文章CSS line-break属性与中文标点换行

.avator::before{
  /**/
  line-break: anywhere; /*任意地方都换行*/
}

这下就没问题了,都是整整齐齐的换行~

下面整理一下,附上完整代码

<ul class="list">
  <li class="item">
    <img class="avator" src="https://tva1.sinaimg.cn/large/008i3skNgy1grgo8qjty1j30e80e8aad.jpg" alt="xboxyan">
    xboxyan
  </li>
  <li class="item">
    <img class="avator" src="" alt="xboxyan">
    xboxyan
  </li>
  <li class="item">
    <img class="avator" src="" alt="前端侦探">
    前端侦探
  </li>
  <li class="item">
    <img class="avator" src="" alt="体验设计部">
    体验设计部
  </li>
</ul>
.list{
  list-style: none;
  padding: 0;
}
.avator{
  width: 40px;
  height: 40px;
  border-radius: 8px;
  overflow: hidden;
  background: bisque;
}
.avator::before{
  content: attr(alt);
  display: flex;
  width: 100%;
  height: 100%;
  background-color: bisque;
  text-transform: uppercase;
  line-height: 40px;
  letter-spacing: 40px;
  text-indent: 40px;
  justify-content: center;
  text-align: center;
  /* word-break: break-all; */
  line-break: anywhere;
  color: rgb(250, 84, 28);
}
.item{
  display: flex;
  align-items: center;
  gap: 15px;
  height: 64px;
  font-size: 18px;
}

效果如文章开头所示,有需要的可以直接用起来了;

五、总结一下

以上就是本文的全部内容了,非常简单实用的一个小功能,下面简单总结一下:

现代浏览器支持 img 伪元素了,并且只有在资源加载失败时才可用,利用这一点可以设置图片占位符。

伪元素通过 attr 属性可以获取 img 标签属性,推荐使用 alt 。

伪元素不能再使用伪元素了 。

增加字符的行间距可以在可视范围内仅看到一个字符 。

垂直居中可以通过行高来实现 。

水平居中可以通过首行缩进 和 flex 居中实现 。

部分特殊符号由于“避尾”或者“避首”特性,导致换行布局错乱 。

line-break 可以打破以上规则 。

唯一的遗憾就是 Safari 不支持图片伪元素,不过没关系,不影响功能,也可以学到一些你可能不知道的小技巧。

来源: 前端侦探

链接: https://www.fly63.com/article/detial/11451


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK