前言
今天将解决 transform导致文字 的模糊问题。 那么?什么时候会触发这种问题呢?在 Google 上,其实我们能搜到非常多类似的案例,总结而言:
一、当文本元素的某个祖先容器存在 transform: translate() 或者 transform: scale() 等 transform 操作时,容易出现这种问题
当然,这只是必要条件,不是充分条件。继续深入探究,会发现,必须还得同时满足一些其它条件:
二、元素作用了 transform: translate() 或者 transform: scale() 后的计算值产生了非整数
例如:
.container {
position: absolute;
width: 1104px;
height: 475px;
top: 50%;
transform: translateY(-50%);
// ...
}
由于元素的高度为 475px,translateY(-50%) 等于 237.5px,非整数,才导致了内部的字体模糊。
但是,需要注意的是,并非所有产生的非整数都会导致了内部的字体模糊。
三、文本内容是否模糊还与屏幕有关,高清屏(dpr > 2)下不容易触发,更多发生在普通屏幕下(dpr = 1)
如何解决上面问题
使用css新特性 round() 函数解决模糊问题
我们可以通过 round() 函数,保证作用了 transform: translate() 或者 transform: scale() 后的计算值一定是正整数,从而避免模糊问题。
譬如,原本的 CSS 如下:
.container {
width: 50vw;
height: 50vh;
transform: translate(-50%, -50%);
}
此时,transform: translate() 的实际最终计算值是会出现小数的。因此,我们可以使用 round() 函数进行取整:
.container {
width: 50vw;
height: 50vh;
transform: translate(round(-50%, 1px), round(-50%, 1px));
}
round() 应用
round() 还有一个有趣用法。我们可以使用 round() 实现类似于 CSS Animation 中的 steps() 步骤动画的效果。
<div></div>
@property --angle {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
div {
width: 200px;
height: 200px;
border-radius: 50%;
background: conic-gradient(#fc0, #fc0 15deg, transparent 15deg, transparent 30deg);
transform: rotate(var(--angle));
animation: propertyRotate 2s infinite linear;
}
@keyframes propertyRotate {
100% {
--angle: 360deg;
}
}
其他css函数
在 CSS 中,存在许多数学函数,这些函数能够通过简单的计算操作来生成某些属性值,例如 :
calc():用于计算任意长度、百分比或数值型数据,并将其作为 CSS 属性值。
min() 和 max():用于比较一组数值中的最大值或最小值,也可以与任意长度、百分比或数值型数据一同使用。
clamp():用于将属性值限制在一个范围内,支持三个参数:最小值、推荐值和最大值。
最近各大浏览器也逐渐开始原生支持的三角函数:
sin()
cos()
tan()
CSS 三角函数语法介绍
.box {
/* 设置元素的宽度为 sin(30deg) 的值 */
width: calc(sin(30deg) * 100px);
/* 设置元素的高度为 cos(45deg) 的值 */
height: calc(cos(45deg) * 100%);
/* 设置元素的透明度为 tan(60deg) 的值 */
opacity: calc(tan(60deg));
}
我们可以通过 transfrom,借助 CSS @Property 属性,来构造一个三角函数的使用场景:
.g-single {
width: 20px;
height: 20px;
background: #000;
border-radius: 50%;
animation: move 5s infinite ease-in-out;
transform: translate(
calc(var(--dis) - 40vw),
calc(5 * sin(var(--angle)) * 1em)
);
}
@keyframes move {
0% {
--dis: 0px;
--angle: 0deg;
}
100% {
--dis: 80vw;
--angle: 1080deg;
}
}
尝试使用三角函数实现波浪线
<div></div>
<div></div>
<div></div>
@function shadowSet($vx, $vy, $color) {
$shadow: 0 0 0 0 $color;
@for $i from 0 through 50 {
$x: calc(2 * sin(#{$i * 15 * 1deg}) * #{$vy});
$y: $i * $vy;
$shadow: $shadow, #{$x} #{$y} 0 0 $color;
}
@return $shadow;
}
div {
margin: auto;
width: 10px;
height: 10px;
border-radius: 50%;
background: #f00;
box-shadow: shadowSet(3px, 3px, #f00);
}
div:nth-child(2) {
width: 6px;
height: 6px;
background: #fc0;
box-shadow: shadowSet(3px, 3px, #fc0);
}
div:nth-child(3) {
width: 4px;
height: 4px;
background: #000;
box-shadow: shadowSet(2px, 2px, #000);
}
今天暂时总结到这里。