Chrome 中的字体粗细 CSS 转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16629725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 22:55:21  来源:igfitidea点击:

Font-Weight CSS Transition in Chrome

cssgoogle-chromefontscss-transitions

提问by Funktr0n

Trying to get font-weightto gracefully transition from '400' to '600' using CSS but it doesn't appear to be working in Chrome. Is this a known bug or am I doing something wrong?

试图font-weight使用 CSS 从“400”到“600”优雅地过渡,但它似乎在 Chrome 中不起作用。这是一个已知的错误还是我做错了什么?

Check the Fiddle here for an example

在此处查看小提琴以获取示例

采纳答案by Funktr0n

Font-weight animation is currently not supported in Chrome and IE-10 based on numerous tests. This may change in the future.

根据大量测试,Chrome 和 IE-10 目前不支持字体粗细动画。这在未来可能会改变。

回答by James Donnelly

The problem is that font weights, when represented numerically, must be a multiple of 100. To animate between 400 and 600, the font would change from 400 to 500 to 600 (3 'frames', if you like) and wouldn't look very smooth. An animation wouldn't increment the weight by 1 each time (400, 401, 402...) it would increment the weight by 100 (400, 500, 600). If your animation lasted 2 seconds, after 1 second the weight would suddenly become 500, and after 2 seconds the weight would suddenly become 600; there are no in-between variations.

问题是字体权重,当用数字表示时,必须是 100 的倍数。要在 400 和 600 之间设置动画,字体将从 400 变为 500 到 600(3 个“框架”,如果您愿意)并且看起来不会非常顺利。动画不会每次都将权重增加 1 (400, 401, 402...) 它会将权重增加 100 (400, 500, 600)。如果你的动画持续2秒,1秒后权重会突然变成500,2秒后权重会突然变成600;没有中间变化。

A further problem with what you're attempting here is that the font you're using (or JSFiddle's default, at least) doesn't have anything different for font-weight:500, meaning it defaults to 400:

您在这里尝试的另一个问题是您使用的字体(或 JSFiddle 的默认字体,至少)没有任何不同的 for font-weight:500,这意味着它默认为 400:

<p style="font-weight:400;">a - 400, normal</p>
<p style="font-weight:500;">a - 500 (no support, defaults to 400)</p>
<p style="font-weight:600;">a - 600 (bold)</p>
<p style="font-weight:650;">a - 650 (not valid, defaults to 400)</p>

http://jsfiddle.net/r4gDh/6/

http://jsfiddle.net/r4gDh/6/

Numeric font weights for fonts that provide more than just normal and bold. If the exact weight given is unavailable, then 600-900 use the closest available darker weight (or, if there is none, the closest available lighter weight), and 100-500 use the closest available lighter weight (or, if there is none, the closest available darker weight). This means that for fonts that provide only normal and bold, 100-500 are normal, and 600-900 are bold.

字体的数字字体权重,提供的不仅仅是普通和粗体。如果给定的确切重量不可用,则 600-900 使用最接近的可用深色重量(或者,如果没有,则使用最接近的可用较轻重量),而 100-500 使用最接近的可用较轻重量(或者,如果没有,最接近的可用深色权重)。这意味着对于仅提供正常和粗体的字体,100-500 是正常的,600-900 是粗体。

https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight

https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight

This basically means that you can't smoothly animate font-weight. Even if you had support for all weights between 100 and 900 the change wouldn't be pleasant and there would be a dramatic change between 500 and 600 (where lighter weightmeets darker weight).

这基本上意味着您无法平滑地设置动画font-weight。即使您对 100 到 900 之间的所有重量都有支持,这种变化也不会令人愉快,并且在 500 和 600 之间(其中较轻的重量遇到较深的重量)也会有显着的变化。

回答by user2943492

I came here to find out the answer myself for how to transition font weight, and was disappointed when I read the approved answer above saying that it can't be done (or at least not very well).

我来这里是为了自己寻找如何转换字体粗细的答案,当我阅读上面批准的答案时说它无法完成(或至少不是很好)时感到失望。

With font-weight animation unavailable, I decided to try another effect, which actually gives you a font-weight effect... which I didn't even think would work for this type of transition.

由于字体粗细动画不可用,我决定尝试另一种效果,它实际上为您提供字体粗细效果……我什至认为它不适用于这种类型的过渡。

Here is how to make the weight grow:

以下是使体重增长的方法:

.weightGrow:hover {
    text-shadow:
    -1px -1px 0 #2DD785,
    1px -1px 0 #2DD785,
    -1px 1px 0 #2DD785,
    1px 1px 0 #2DD785;
    -webkit-transition: all .5s;
    -moz-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
}

Perfectly smooth and exactly what I was looking for when I first arrived on this page. Hope it helps someone.

非常流畅,正是我第一次到达此页面时所寻找的。希望它可以帮助某人。

回答by nim

Fonts are not simple vector image collections (that's why svg fonts never took off). Opentype fonts include all kinds of magic to clamp fonts to the pixel grid, which makes it unrealistic to expect a font family to ever include every possible weight value.

字体不是简单的矢量图像集合(这就是 svg 字体从未流行的原因)。Opentype 字体包括将字体固定到像素网格的各种魔法,这使得期望字体系列包含所有可能的权重值是不现实的。

Because fonts are not simple vector image collections they will also never resize linearly – there will be bumps to take the pixel grid into account.

因为字体不是简单的矢量图像集合,它们也永远不会线性调整大小 - 将像素网格考虑在内。

This Google whitepaper explains why linear resizing does not work for text on current screens https://docs.google.com/document/d/1wpzgGMqXgit6FBVaO76epnnFC_rQPdVKswrDQWyqO1M/edit

这份 Google 白皮书解释了为什么线性调整大小不适用于当前屏幕上的文本 https://docs.google.com/document/d/1wpzgGMqXgit6FBVaO76epnnFC_rQPdVKswrDQWyqO1M/edit

which is why no browser will attempt it and they will all rely on pre-computed font weights.

这就是为什么没有浏览器会尝试它并且它们都将依赖于预先计算的字体权重。

That may change in a decade when retina displays are the lowest common denominator but current font tech targets current screens.

当视网膜显示是最小公分母但当前的字体技术针对当前屏幕时,这可能会在十年内发生变化。

This Microsoft whitepaper documents some standard font weight values http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-components-postattachments/00-02-24-90-36/WPF-Font-Selection-Model.pdf

此 Microsoft 白皮书记录了一些标准字体粗细值 http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-components-postattachments/00-02-24-90-36/WPF-Font-Selection-Model .pdf

(but just because they are documented does not mean the number of fonts that actually include all of them is not quite small)

(但仅仅因为它们被记录并不意味着实际包含所有这些的字体数量不是很小)

You can probably achieve the effect you want with an svg font and some javascript. The svg font will be crap for text use though.

您可以使用 svg 字体和一些 javascript 来实现您想要的效果。svg 字体对于文本使用来说将是废话。

回答by Rolf

I seem to have obtained a "font-weight" transition effect accidentally, by doing a quick color transition (light gray to dark blue) at the same time.

通过同时进行快速颜色过渡(浅灰色到深蓝色),我似乎意外获得了“字体粗细”过渡效果。

回答by Idra

Although there is no direct way to get the font-weight to smoothly transition, I have found a way to do this indirectly (although with some limitations).

虽然没有直接的方法让字体粗细平滑过渡,但我找到了一种间接的方法(尽管有一些限制)。

In essence you can simply use one of the pseudo elements in order to make a mirror copy of the element whom font you want to transition to bold, where the font-weight on the pseudo element is bold and the opacity is 0. And on hover simply transition the pseudo element's opacity and that does the trick with a very smooth transition.

本质上,您可以简单地使用伪元素之一来制作要转换为粗体的元素的镜像副本,其中伪元素的字体粗细为粗体,不透明度为 0。悬停时只需转换伪元素的不透明度,即可实现非常平滑的转换。

You can see a demo here:
http://jsfiddle.net/r4gDh/45/

你可以在这里看到一个演示:http:
//jsfiddle.net/r4gDh/45/

HTML:

HTML:

<div class="element" data-text="text will turn to bold on hover">
  text will turn to bold on hover
</div>

In the HTML you can already see one of the limitations, because we are using pseudo elements we need to pass the contents of the element as an attribute as well, so the content is duplicated.

在 HTML 中,您已经可以看到其中一个限制,因为我们使用的是伪元素,因此我们还需要将元素的内容作为属性传递,因此内容是重复的。

CSS:

CSS:

.element,
.element::before {
    background: red;
    font-weight:normal;
    font-size:40px;

    text-align:center;

    display: inline-block;

    padding: 0px 30px 0px 30px;

    position: relative;
    top: 0;
    left: 0;
}
.element::before {
    position: absolute;
    top: 0;
    left: 0;

    width: 100%;
    height: 100%;

    padding: 0;

    content: attr(data-text);
    opacity: 0;

    font-weight: bold;

    transition: all 1s linear;
}
.element:hover::before {
    opacity: 1;
}

The second limitation comes from the nature of the technique, namely because you are simply overlaying the pseudo element over the original, then the element needs to have a solid background or this will not work, because the original element will remain visible in the background.

第二个限制来自该技术的性质,即因为您只是将伪元素覆盖在原始元素上,那么该元素需要具有纯色背景,否则这将不起作用,因为原始元素将在背景中保持可见。

One thing you should really keep an eye on is that the pseudo element and the original element have the same dimensions, to this end, in the demo, I've removed the padding on the pseudo element, so you may need to do something similar.

您真正应该注意的一件事是伪元素和原始元素具有相同的尺寸,为此,在演示中,我已经删除了伪元素上的填充,因此您可能需要做一些类似的事情.

As you can see, this way of getting the font-weight transition is not without it's problems and far from ideal, but this is the best I can currently think of and in limited cases like for buttons and what not this is quite useful and if done correctly will look decent even in legacy browsers.

如您所见,这种获得字体粗细过渡的方法并非没有问题,也远非理想,但这是我目前能想到的最好的方法,并且在有限的情况下,例如按钮,这非常有用,如果即使在传统浏览器中,正确完成也会看起来不错。

回答by Michael Chen

I've tweaked @Idra's fiddle to make the normal to bold transition a bit smoother. Here's the fiddle: http://jsfiddle.net/y7rLwx95/

我调整了@Idra 的小提琴,使从正常到粗体的过渡更加平滑。这是小提琴:http: //jsfiddle.net/y7rLwx95/

Changes... Since the text width will get wider when going to bold, I've added an initial "stretch" transition by increasing the letter spacing:

更改...由于文本宽度在加粗时会变宽,因此我通过增加字母间距添加了初始“拉伸”过渡:

.element:hover {
   letter-spacing: 0.9px;
   transition: all .3s linear;
}

Then delayed the fading in of the bold ::before element:

然后延迟粗体 ::before 元素的淡入:

.element:hover::before {
   opacity: 1;
   transition-delay: .2s
}

Also some additional tweaks here:

这里还有一些额外的调整:

.element::before {
   transition: all .3s linear;  /* replace */
   letter-spacing: 0;           /* additional */
}

The transition timing is just whatever feels right to me. The original idea @Idra posted is significant to me. I accept that fact that the widths shouldbe different between normal and bold, as that's the intent of different font weights. So really the challenge, IMHO, is to figure out how to go between the 2 looks in a smooth, no jarring way. This seems to be the best solution so far I've found.

过渡时间对我来说是正确的。@Idra 发布的最初想法对我来说很重要。我接受正常和粗体之间的宽度应该不同的事实,因为这是不同字体粗细的意图。因此,恕我直言,真正的挑战是弄清楚如何以平稳,没有刺耳的方式在两种外观之间切换。到目前为止,这似乎是我找到的最佳解决方案。