在悬停时使用字母间距保持宽度

Posted

技术标签:

【中文标题】在悬停时使用字母间距保持宽度【英文标题】:Keep width when using letter-spacing on hover 【发布时间】:2019-06-23 17:35:20 【问题描述】:

我有一些基本的按钮样式,在 :hover 上我添加了 letter-spacing 属性:

.btn 
  display: inline-block;
  text-align: center;
  background-color: transparent;
  border: 1px solid transparent;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: all 0.2s ease;


.btn-primary 
  background-color: #8065F1;
  color: #FFFFFF;


.btn-large 
  border-radius: 32px;
  box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
  padding: 0.25rem 3rem;
  font-size: 1.5rem;
  text-transform: uppercase;


.btn:hover 
  letter-spacing: 4px;
<button type="button" class="btn btn-primary btn-large">Lorem</button>

有没有办法使width 不扩展?喜欢加min/max-width?但是问题是button 元素可以包含不同的字符串长度:

.btn 
  display: inline-block;
  text-align: center;
  background-color: transparent;
  border: 1px solid transparent;
  padding: 0.375rem 0.75rem;
  box-shadow: 0 2px 80px 0 rgba($grey, 0.23);
  font-size: 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: all 0.2s ease;


.btn-primary 
  background-color: #8065F1;
  color: #FFFFFF;


.btn-large 
  border-radius: 32px;
  -webkit-box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
  box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
  padding: 0.25rem 3rem;
  font-size: 1.5rem;
  text-transform: uppercase;
  min-width: 240px;


.btn:hover 
  letter-spacing: 4px;
<p>I need this "effect" (I added some min-width):</p>
<button type="button" class="btn btn-primary btn-large">Lorem</button>

<p>However it won't work for larger strings</p>
<button type="button" class="btn btn-primary btn-large">Lorem Ipsum</button><br><br>
<button type="button" class="btn btn-primary btn-large">Lorem Ipsum Dolor</button>

我知道我可以使用 JS 并在其上附加固定宽度的元素,但是我正在寻找一种 CSS 解决方案 - 如果有的话?

【问题讨论】:

也许和padding一起玩会有所帮助 另一个问题是,根据字母的数量,宽度会增加很多,您将如何管理? @TemaniAfif 是的,这是主要问题。正如我所说,它可以用 JS 完成,但我想知道是否有 CSS 解决方案。编辑 - 我明白你的意思,如果字符串更大,那么只有宽度是不够的。有办法吗? @JoykalInfotech 你能举个例子吗? 我想过,但我意识到这不是一个合适的解决方案。 【参考方案1】:

近似这个的想法是复制文本,考虑一个隐藏的文本已经有letter-spacing 和另一个在顶部的动画,以填充隐藏文本已经定义的空间:

这是一个让文本颜色与背景颜色相同的想法:

.btn 
  display: inline-block;
  text-align: center;
  background-color: transparent;
  border: 1px solid transparent;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-bottom:10px;


.btn-primary 
  background-color: #8065F1;
  color: #FFFFFF;


.btn-large 
  border-radius: 32px;
  box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
  padding: 0.25rem 3rem;
  font-size: 1.5rem;
  text-transform: uppercase;


.btn::before 
  content:attr(data-text);
  position:absolute;
  left:0;
  right:0;
  text-align:center;
  letter-spacing: initial;
  color:#fff;
  transition: all 0.2s ease;

.btn 
  letter-spacing: 4px;
  color:#8065F1;
  position:relative;

.btn:hover::before 
  letter-spacing: 4px;
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem">Lorem</button></div>

<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum">Lorem Ipsum</button></div>
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum Dolor">Lorem Ipsum Dolor</button></div>

另一个使用 opacity 和两个伪元素以防背景不是纯色:

.btn 
  display: inline-block;
  text-align: center;
  background-color: transparent;
  border: 1px solid transparent;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-bottom:10px;


.btn-primary 
  background: linear-gradient(#8065F1,purple);
  color: #FFFFFF;


.btn-large 
  border-radius: 32px;
  box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
  padding: 0.25rem 3rem;
  font-size: 1.5rem;
  text-transform: uppercase;

.btn 
  position:relative;
  font-size:0;

.btn::before 
  content:attr(data-text);
  position:absolute;
  left:0;
  right:0;
  text-align:center;
  letter-spacing: initial;
  font-size: 1.5rem;
  transition: all 0.2s ease;

.btn::after 
  content:attr(data-text);
  letter-spacing: 4px;
  opacity:0;
  font-size: 1.5rem;

.btn:hover::before 
  letter-spacing: 4px;
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem">Lorem</button></div>

<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum">Lorem Ipsum</button></div>
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum Dolor">Lorem Ipsum Dolor</button></div>

【讨论】:

看起来像一个“黑客”但很好 - 从来没有想到过。有趣的是没有“更简单”的解决方案。 @Vucko 我不认为有一个 simple 解决方案,因为对于每个字母,您将增加 xpx,因此它是动态的,您无法知道总体的多少Xpx 会,但可能有一些我没有想到的事情:)【参考方案2】:

如何关闭 box-sizing,然后使用 百分比 作为填充?无论您的内容大小如何,它都应该可以正常工作,但我的数字可能有误,因此您需要调整数字以使其准确。

    .wrapper
        display:inline-block;
    
    button
        box-sizing: content-box;
        padding: 0 10.4%;
        border: none;
        width: 100%;
        font-size:13px;
    
    button:hover
        letter-spacing:0.1em;
        padding:0;
    
    .outer-wrapper
        
    
    <div class="outer-wrapper">
        <div class="wrapper">
            <button class='button'>Small Text</button>  
        </div>
    </div>
    <div class="outer-wrapper">
        <div class="wrapper">
            <button class='button'>Much much bigger text</button>  
        </div>
    </div>
    <div class="outer-wrapper">
        <div class="wrapper">
            <button class='button'>Small TextSmall TextSmall TextSmall TextSmall Text</button>  
        </div>
    </div>
    

编辑:嗯,它...或多或少的工作,除了它原来是不可能。无论我如何微调它,由于浏览器渲染子像素的差异,我都会遇到问题。 (浏览器对 rem 的舍入显然与 % 不同,这意味着纯 CSS 不可能做到这一点。)

【讨论】:

@Vucko 我已经修改了我的答案.....但现在我确信这是不可能的,因为浏览器根据 % 或 px 呈现子像素的方式不同。

以上是关于在悬停时使用字母间距保持宽度的主要内容,如果未能解决你的问题,请参考以下文章

列表项悬停间距[重复]

如何在悬停时保持 Bootstrap 弹出框活着?

当您使用 Javascript 单击或停止悬停时,如何使 CSS 悬停内容保持原位?

使用jQuery单击时保持图像悬停按钮

如何在悬停时获得实际的 DOM CSS 宽度? [复制]

悬停时保持动画的变换位置