Chrome中的字体权重转换

时间:2021-05-23 12:47:43

Trying to get font-weight to 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?

尝试使用CSS将font-weight从'400'优雅地转换为'600',但它似乎不适用于Chrome。这是一个已知的错误还是我做错了什么?

Check the Fiddle here for an example

在这里查看小提琴以获取示例

7 个解决方案

#1


47  

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的默认字体)对于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 weight meets darker weight).

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

#2


13  

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目前不支持基于大量测试的字体权重动画。这可能在将来发生变化。

#3


7  

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字体虽然是文本使用的废话。

#4


6  

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.

当我第一次到达这个页面时,非常流畅,正是我正在寻找的东西。希望它可以帮到某人。

#5


4  

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.

我似乎偶然通过快速颜色过渡(浅灰色到深蓝色)获得了“字体 - 重量”过渡效果。

#6


2  

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.

本质上,您可以简单地使用其中一个伪元素,以便为要转换为粗体的字体生成元素的镜像副本,其中伪元素上的font-weight为粗体,不透明度为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.

正如你所看到的,这种获得字体 - 权重转换的方式并非没有它的问题而且远非理想,但这是我目前能想到的最好的,在有限的情况下,如按钮,这不是很有用,如果正确完成即使在旧版浏览器中看起来也不错。

#7


0  

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:

然后延迟了bold :: 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 should be 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发布的最初想法对我很重要。我接受这样的事实:正常和粗体之间的宽度应该是不同的,因为这是不同字体粗细的意图。所以真正的挑战,恕我直言,是要弄清楚如何以平滑,无刺耳的方式在两个外观之间进行。到目前为止,这似乎是我发现的最佳解决方案。

#1


47  

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的默认字体)对于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 weight meets darker weight).

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

#2


13  

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目前不支持基于大量测试的字体权重动画。这可能在将来发生变化。

#3


7  

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字体虽然是文本使用的废话。

#4


6  

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.

当我第一次到达这个页面时,非常流畅,正是我正在寻找的东西。希望它可以帮到某人。

#5


4  

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.

我似乎偶然通过快速颜色过渡(浅灰色到深蓝色)获得了“字体 - 重量”过渡效果。

#6


2  

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.

本质上,您可以简单地使用其中一个伪元素,以便为要转换为粗体的字体生成元素的镜像副本,其中伪元素上的font-weight为粗体,不透明度为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.

正如你所看到的,这种获得字体 - 权重转换的方式并非没有它的问题而且远非理想,但这是我目前能想到的最好的,在有限的情况下,如按钮,这不是很有用,如果正确完成即使在旧版浏览器中看起来也不错。

#7


0  

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:

然后延迟了bold :: 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 should be 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发布的最初想法对我很重要。我接受这样的事实:正常和粗体之间的宽度应该是不同的,因为这是不同字体粗细的意图。所以真正的挑战,恕我直言,是要弄清楚如何以平滑,无刺耳的方式在两个外观之间进行。到目前为止,这似乎是我发现的最佳解决方案。