6

父元素transform小数导致子元素文字外边缘模糊解决方案,及css新特性介绍

 9 months ago
source link: https://www.haorooms.com/post/css_transform_mhround
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

父元素transform小数导致子元素文字外边缘模糊解决方案,及css新特性介绍

2023年9月17日 5049次浏览

今天将解决 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);
}

今天暂时总结到这里。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK