CSS:粗体化一些文本而不改变其容器的大小

Mal*_*ala 94 css fonts menu

我有一个水平导航菜单,基本上只是一个<ul>元素并排设置.我没有定义宽度,只是使用填充,因为我希望宽度由菜单项的宽度定义.我加粗了当前所选的项目.

麻烦的是,在粗体中,单词变得稍微宽一些,这导致其余元素稍微向左或向右移动.有没有一种聪明的方法可以防止这种情况发生?告诉padding忽略由粗体引起的额外宽度的问题?我的第一个想法是简单地从"活动"元素的填充中减去几个像素,但这个数量会有所不同.

如果可能的话,我想避免在每个条目上设置静态宽度然后居中而不是我当前拥有的填充解决方案,以便将来对条目的更改变得简单.

Tho*_*eir 131

我有同样的问题,但有一点点妥协得到了类似的效果,我使用了文字阴影.

li:hover {text-shadow:0px 0px 1px black;}
Run Code Online (Sandbox Code Playgroud)

这是一个有效的例子:

body {
  font-family: segoe ui;
}

ul li {
  display: inline-block;
  border-left: 1px solid silver;
  padding: 5px
}

.textshadow :hover {
  text-shadow: 0px 0px 1px black;
}

.textshadow-alt :hover {
  text-shadow: 1px 0px 0px black;
}

.bold :hover {
  font-weight: bold;
}
Run Code Online (Sandbox Code Playgroud)
<ul class="textshadow">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li><code>text-shadow: 0px 0px 1px black;</code></li>
</ul>

<ul class="textshadow-alt">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li><code>text-shadow: 1px 0px 0px black;</code></li>
</ul>

<ul class="bold">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li><code>font-weight: bold;</code></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

jsfiddle的例子

  • 我喜欢这个解决方案,虽然我建议将其翻到1px 0px 0px.看起来更加大胆. (47认同)
  • 我认为这不是一个好的解决方案,粗体字体不仅仅是更宽的字体,大多数字体都有特殊的字母形式用于粗体粗细。 (5认同)
  • 我使用`-0.5px 0 #fff,0.5px 0 #ffff`,因为我们可以看到文本本身和阴影之间的小差距.而且当文字是粗体时,它会增加双方的重量. (4认同)
  • 仅添加`li:hover {text-shadow: 1px 0 0 black;}` 会导致文字之间的间距太小。为了再次改进,我们还设置了`li {letter-spacing: 1px;}` (2认同)

小智 84

使用:: after的最佳工作解决方案

HTML

<li title="EXAMPLE TEXT">
  EXAMPLE TEXT
</li>
Run Code Online (Sandbox Code Playgroud)

CSS

li::after {
  display: block;
  content: attr(title);
  font-weight: bold;
  height: 1px;
  color: transparent;
  overflow: hidden;
  visibility: hidden;
}
Run Code Online (Sandbox Code Playgroud)

它添加了一个不可见的伪元素,宽度为粗体文本,由title属性提供.

text-shadow解决方案在Mac上看起来不自然,并没有利用Mac上的文字渲染提供的所有美感.. :)

http://jsfiddle.net/85LbG/

信用:https://stackoverflow.com/a/20249560/5061744

  • 这是最可靠和最干净的解决方案,它只是为元素中的粗体文本保留空间.在我的例子中,附加的伪元素引起了高度的变化.将负`margin-top`添加到`:: after`块解决了这个问题. (7认同)
  • 惊人的。这应该是最好的答案。请注意,如果元素与 li 不同,则可能必须使用 display:block; 在 :after 父元素上。 (3认同)
  • 这个解决方案很棒!我使用 JS 添加了一个包含元素文本的“数据内容”属性,这样我就可以避免更改 HTML。 (2认同)
  • 当您被迫使用“title”并且如果没有“title”属性它甚至无法工作时,这如何是一个正确的解决方案...... (2认同)
  • 最佳解决方案。补充一点:使用 `height: 0;` 是安全的 (2认同)

Ada*_*atz 24

最便携和视觉上令人愉悦的解决方案是使用text-shadow.这修改并显示了使用Alexxali和我自己的调整的Thorgeir 答案的例子:

  li:hover { text-shadow: -0.06ex 0 black, 0.06ex 0 black; }
Run Code Online (Sandbox Code Playgroud)

这会将black每个字母两侧的微小"阴影"放在黑色(使用字体的颜色名称/代码代替,如果需要),使用可以使用字体渲染正确缩放的单位.

警告 警告: px值确实支持十进制值,但是当字体大小更改时它们看起来不那么好(例如,用户使用Ctrl+ 缩放视图+).请改用相对值.

这个答案使用ex单位的分数,因为它们与字体一起缩放.
在〜大多数浏览器默认值*中,期望1ex8px因此0.025ex0.1px.

你自己看:

li             { color: #000; } /* set text color just in case */
.shadow0       { text-shadow: inherit; }
.shadow2       { text-shadow: -0.02ex 0 #000, 0.02ex 0 #000; }
.shadow4       { text-shadow: -0.04ex 0 #000, 0.04ex 0 #000; }
.shadow6       { text-shadow: -0.06ex 0 #000, 0.06ex 0 #000; }
.shadow8       { text-shadow: -0.08ex 0 #000, 0.08ex 0 #000; }
.bold          { font-weight: bold; }
.bolder        { font-weight: bolder; }
.after span        { display:inline-block; font-weight: bold; } /* workaholic… */
.after:hover span  { font-weight:normal; }
.after span::after { content: attr(title); font-weight: bold; display:block; 
                     height: 0; overflow: hidden; }
.ltrsp         { letter-spacing:0; font-weight:bold; } /* @cgTag */
li.ltrsp:hover { letter-spacing:0.0125ex; }
li:hover       { font-weight: normal!important; text-shadow: none!important; }
Run Code Online (Sandbox Code Playgroud)
<li class="shadow0">MmmIii123 This line tests shadow0 (plain)</li>
<li class="shadow2">MmmIii123 This line tests shadow2 (0.02ex)</li>
<li class="shadow4">MmmIii123 This line tests shadow4 (0.04ex)</li>
<li class="shadow6">MmmIii123 This line tests shadow6 (0.06ex)</li>
<li class="shadow8">MmmIii123 This line tests shadow8 (0.08ex)</li>
<li class="after"><span title="MmmIii123 This line tests [title]"
                   >MmmIii123 This line tests [title]</span> (@workaholic…)</li>
<li class="ltrsp"  >MmmIii123 This line tests ltrsp (@cgTag)</li>
<li class="bold"   >MmmIii123 This line tests bold</li>
<li class="bolder" >MmmIii123 This line tests bolder</li>
<li class="shadow2 bold">MmmIii123 This line tests shadow2 (0.02ex) + bold</li>
<li class="shadow4 bold">MmmIii123 This line tests shadow4 (0.04ex) + bold</li>
<li class="shadow6 bold">MmmIii123 This line tests shadow6 (0.06ex) + bold</li>
<li class="shadow8 bold">MmmIii123 This line tests shadow8 (0.08ex) + bold</li>
Run Code Online (Sandbox Code Playgroud)

将鼠标悬停在渲染线上以查看它们与标准文本的区别.

改变浏览器的缩放级别(Ctrl+ +Ctrl+ -)以查看它们的变化情况.

我在这里添加了另外两个解决方案用于比较:@ cgTag的字母间距技巧,它不能很好地工作,因为它涉及猜测字体宽度范围,而@ workaholic_gangster911的::绘制技巧之后,留下了尴尬的额外空间,因此粗体文本可以扩展没有轻推相邻的文本项目(我把粗体文本后面的属性放在一起,这样你就可以看到它不会移动).


将来,我们将拥有更多可变字体,可以通过更改字体等级来实现font-variation-settings. 浏览器支持正在增加(Chrome 63 +,Firefox 62+),但这仍然需要的不仅仅是标准字体,而且很少有现有字体支持它.

如果你嵌入了一个可变字体,你将能够像这样使用CSS:

/* Grade: Increase the typeface's relative weight/density */
@supports (font-variation-settings: 'GRAD' 150) {
  li:hover { font-variation-settings: 'GRAD' 150; }
}
/* Failover for older browsers: tiny shadows at right & left of the text
 * (replace both instances of "black" with the font color) */
@supports not (font-variation-settings: 'GRAD' 150) {
  li:hover { text-shadow: -0.06ex 0 black, 0.06ex 0 black; }
}
Run Code Online (Sandbox Code Playgroud)

在Mozilla可变字体指南中有一个带滑块的现场演示,可以播放各种等级.谷歌网上可变字体简介有一个动画GIF,展示高等级和无等级之间的切换:

动画Amstelvar Alpha字体演示,带有翻转等级轴


Rea*_*lar 16

我发现当你将字母间距调整为1px时,大多数字体的大小都相同.

a {
   letter-spacing: 1px;
}

a:hover {
   font-weight: bold;
   letter-spacing: 0px;
}
Run Code Online (Sandbox Code Playgroud)

虽然这确实改变了常规字体,因此每个字母都有一个额外的像素间距.对于菜单,标题很短,不会出现问题.

  • 这是最好和最被低估的解决方案,虽然我改变了它,因此它从0开始并在粗体时转到负字母间距.你也必须为每种字体和字体大小微调它.我还更新了@ Thorgeir的小提琴,包括这个(作为第二个解决方案)[jsfiddle.net/dJcPn/50/](http://jsfiddle.net/dJcPn/50/) (2认同)

Oli*_*ver 9

有关更新的答案,您可以使用-webkit-text-stroke-width

.element {
  font-weight: normal;
}

.element:hover {
  -webkit-text-stroke-width: 1px;
  -webkit-text-stroke-color: black;
}
Run Code Online (Sandbox Code Playgroud)

这避免了任何伪元素(这对屏幕阅读器来说是一个加分项)和文本阴影(看起来很乱,但仍会产生轻微的“跳跃”效果)或设置任何固定宽度(这可能不切实际)。

它还允许您将元素设置为大于 1px 的粗体(理论上,您可以将字体设置为您喜欢的粗体,也可以是一种粗体版本的粗体练习,用于创建没有粗体的字体变体,如自定义字体(编辑:可变字体贬低此建议)。尽管应该避免这种情况,因为它可能会使某些字体显得粗糙和锯齿状)

我这绝对适用于 Edge、Firefox、Chrome 和 Opera(发布时)和 Safari编辑:@Lars Blumberg 感谢您确认)。它不适用于 IE11 或更低版本。

还要注意,它使用-webkit前缀,所以这不是标准的,将来可能会取消支持,所以不要依赖这个粗体真的很重要 - 最好避免这种技术,除非它只是为了美观。

  • 这在 Firefox 中有效,但请注意,它可能看起来非常难看,有点模糊。 (4认同)

aar*_*rkk 9

我强烈建议在此用例中尝试使用单宽字体。

它们仍然是比例字体(与等宽字体相反),但它们在不同的字体粗细中占据相同的大小不需要 CSS、JS 或花哨的技巧来保持大小不变​​。它直接融入到字体中。

以下是这篇优秀文章中的示例,比较了比例字体 IBM Plex Sans 和 uniwidth Recursive。

与等宽字体成比例比较

您可以尝试的免费单宽字体有:

还有许多通过上述文章链接的非免费选项。


dan*_*gee 5

这是一个非常古老的问题,但我正在重新审视它,因为我在正在开发的应用程序中遇到了这个问题,并在这里找到了所有想要的答案。

\n\n

(跳过这一段,看 TL;DR...)我正在使用 cloud.typography.com 上的 Gotham webfont,并且我有一些按钮,这些按钮开始是空心的(具有白色边框/文本和透明背景)并获取悬停时的背景颜色。我发现我使用的一些背景颜色与白色文本没有很好的对比,所以我想将这些按钮的文本更改为黑色,但是 \xe2\x80\x94 无论是因为视觉技巧还是常见抗锯齿方法 \xe2\x80\x94 浅色背景上的深色文本总是比深色背景上的白色文本显得更轻。我发现将深色文本的权重从 400 增加到 500 可以保持几乎完全相同的“视觉”权重。然而,它只是将按钮宽度增加了一点点 \xe2\x80\x94 像素的一小部分 \xe2\x80\x94 但这足以使按钮看起来稍微“抖动”,我想摆脱它的。

\n\n

解决方案:

\n\n

显然,这是一个非常棘手的问题,因此需要一个棘手的解决方案。最终,我按照上面推荐的 cgTag 在粗体文本上使用了负数letter-spacing,但 1px 就有点过大了,所以我只是精确计算了我需要的宽度。

\n\n

通过检查 Chrome devtools 中的按钮,我发现按钮的默认宽度为 165.47px,悬停时为 165.69px,相差 0.22px。该按钮有 9 个字符,因此:

\n\n

0.22 / 9 = 0.024444 像素

\n\n

通过将其转换为 em 单位,我可以使调整字体大小变得不可知。我的按钮使用的字体大小为 16px,因此:

\n\n

0.024444 / 16 = 0.001527em

\n\n

因此,对于我的特定字体,以下 CSS 使按钮在悬停时宽度完全相同

\n\n
.btn {\n  font-weight: 400;\n}\n\n.btn:hover {\n  font-weight: 500;\n  letter-spacing: -0.001527em;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

通过一些测试并使用上面的公式,您可以找到适合您情况的正确letter-spacing值,并且无论字体大小如何,它都应该有效。

\n\n

需要注意的是,不同的浏览器使用的子像素计算略有不同,因此,如果您的目标是达到这种强迫症级别的子像素完美精度,则需要重复测试并为每个浏览器设置不同的值浏览器。针对浏览器的 CSS 样式通常不受欢迎,这是有充分理由的,但我认为这是一个用例,它是唯一有意义的选择。

\n


Dav*_*ave -1

有趣的问题。我想你用的是浮动,对吧?

好吧,我不知道您可以使用任何技术来消除这种字体放大,因此他们会尝试适应所需的最小宽度 - 并且不同的字体厚度会改变该值。

我知道避免这种变化的独特解决方案是您所说的您不想要的解决方案:将固定大小设置为 li。