bug 记录 - 字符加粗导致宽度变化抖动问题

发现问题

  • 左对齐的横向列表,宽度不固定,由文本内容和 padding 撑开
  • 有的文本中包含符号、英文、数字
  • 鼠标悬浮时添加加粗效果,font-weight: bold
  • 含英文文本,正常情况,宽度是 148.34px,hover 加粗后,宽度变成了 151.19px
  • 含数字文本,正常情况,宽度是 131.64px,hover 加粗后,宽度变成了 133.33px
  • 含符号文本,正常情况,宽度是 113.89px,hover 加粗后,宽度变成了 114.45px

解决问题

  • 盒子宽度需要根据文本字数长度变化而变化,所以宽度不可以写死
  • 盒子宽度有两个值,一种是初始状态宽度 width1,一种是文本加粗后的宽度 width2
  • 如果初始状态,盒子宽度就保持为 width2,就可以避免悬浮加粗抖动的问题了
  • 可以利用伪元素和 visibility 属性进行隐形占位
  • 添加伪元素,利用 attr 属性,拿到文本内容,切换成 block 模块换行,顶开盒子的宽度
  • 伪元素高度设置为 0,不影响原始文本的竖向居中
  • 伪元素设置为 visibility: hidden; 元素隐藏,但是占位
  • 含英文文本,正常情况,宽度已经是 151.19px 了,悬浮后还是 151.19px,宽度未变化,盒子不会再抖动

完整示例

html 复制代码
<body>
  <div>
    <div class="list">
      <div class="sinTitle" title="英文内容wenzi">英文内容wenzi</div>
      <div class="sinTitle" title="文字内容">文字内容</div>
      <div class="sinTitle" title="数字内容123">数字内容123</div>
      <div class="sinTitle" title="文字内容">文字内容</div>
      <div class="sinTitle" title="符号内容#">符号内容#</div>
      <div class="sinTitle" title="文字内容">文字内容</div>
    </div>
  </div>
  <style lang="css">
    .list {
      height: 40px;
      background: #efefef;
      display: flex;
      align-items: center;
      justify-content: flex-start;
    }

    .sinTitle {
      padding: 0 20px;
      cursor: pointer;
      border-right: 1px solid #333;
    }

    .sinTitle:last-child {
      border: none;
    }

    .sinTitle:hover {
      font-weight: bold;
    }

    .sinTitle::after {
      content: attr(title);
      font-weight: bold;
      display: block;
      height: 0;
      visibility: hidden;
    }
  </style>

</body>