transform 文字模糊
2019-06-24 本文已影响2人
恬雅过客
自从发现
transform
里的translate
后,自己定义弹窗提示类的都用此属性和position: fixed;
。然而,今天突然发现,以往好好的效果,今天出现了文字模糊的情况。然后网上搜了资料,加上自己写demo验证,发现确实有这种情况,只是触发的条件,一般不会碰到而已。
问题:transform 文字模糊
此处只讨论position: fixed;
+transform: translate3d(x,y,0);
的场景,网上不少资料说,是因为transform
的标签元素不是偶数导致的,经过我的验证,我觉得不准确,因为使用transform: translate(x,y,0);
时,浏览器会根据该标签元素宽高加上transform属性计算出位置的x和y坐标位置,其实最终的计算结果有小数点都会导致文字模糊的情况。
原因:transform变换会在浏览器上单独创建一个绘画层并重新进行渲染,rotate渲染的时候,由于图层渲染的时候也处理了周围的文字,如果高度为奇数的文字可能会存在半个像素的计算量,浏览器对这半个像素会进行优化渲染,所以边缘会出现模糊的情况。
下面上效果图和源代码:
效果图:
transform-test0.png
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<title>transform 文字模糊问题</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.clear:after{
content: '';
display: block;
width: 0;
height: 0;
clear: both;
}
body{
line-height: 24px;
font: 14px Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif;
}
h1,h2,h3{
font-weight: 400;
}
.con{
position: relative;
width: 100%;
height: 1000px;
background: #eee;
}
.layerdiv {
/*w:231,h: 72;*/
background: #dedada;
position: fixed;
z-index: 1000;
top: 50%;
left: 50%;
border-radius: 3px;
transform: translate(-50%, -50%);
width: 232px;
}
.layerdiv1 {
background: #dedada;
position: fixed;
z-index: 1000;
top: 50%;
left: 50%;
border-radius: 3px;
transform: translate(-50%, 60%);
}
.layerdiv2 {
background: #dedada;
position: fixed;
z-index: 1000;
top: 50%;
left: 50%;
border-radius: 3px;
transform: translate(-50%,-123.5px);
width: 232px;
}
</style>
</head>
<body>
<div class="layerdiv">
<h2>测试文字模糊问题嘿嘿嘿</h2>
<h3>0测试文字模糊问题嘿嘿嘿</h3>
<h4>fixed+transform(整数)</h4>
</div>
<div class="layerdiv1">
<h2>测试文字模糊问题嘿嘿嘿</h2>
<h3>1测试文字模糊问题嘿嘿嘿</h3>
<h4>fixed+transform(非整数)</h4>
</div>
<div class="layerdiv2">
<h2>测试文字模糊问题嘿嘿嘿</h2>
<h3>2测试文字模糊问题嘿嘿嘿</h3>
<h4>fixed+transform(非整数)</h4>
</div>
<div class="con">
带滚动条的内容页
</div>
</body>
</html>
解决方法
- 宽高可固定:尽量把你的弹窗定义成偶数,这样
transform: translate3d(-50%,-50%,0);
计算的最终位置坐标就不会带小数(这时,其实不需要用transform属性也能解决,margin-left和margin-top就可以)。(适用场景:窄) - 宽高不固定:(需要多加一层div标签,最后会附上代码)
- 利用flex布局解决(适用场景:非常广)
- 利用inline-block解决(适用场景:非常广)
- 利用table布局解决(适用场景:比较广)
解决方式的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<title>transform 文字模糊问题</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.clear:after{
content: '';
display: block;
width: 0;
height: 0;
clear: both;
}
body{
line-height: 24px;
font: 14px Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif;
}
h1,h2,h3{
font-weight: 400;
}
.con{
position: relative;
width: 100%;
height: 1000px;
background: #eee;
}
.layerdiv {
background: #dedada;
position: fixed;
z-index: 1000;
top: 50%;
left: 50%;
border-radius: 3px;
transform: translate(-50%, -200%);
width: 232px;
height: 70px;
}
/*flex布局解决方式*/
.layerdiv-flex {
display: flex;
width: 100%;
height: 100%;
position: fixed;
z-index: 9999;
align-items: center;
justify-content: center;
/*background: rgba(0,0,0,0.5);*/
}
.layerdiv-flex .tips{
position: relative;
background: #dedada;
box-shadow: 0 3px 6px #f00;
}
/*inline-block布局解决方式*/
.layerdiv-inline {
position: fixed;
z-index: 9999;
top: 0;
bottom: 0;
left: 0;
right: 0;
/*background: rgba(0,0,0,0.5);*/
text-align: center;
}
.layerdiv-inline:after {
content: "";
display: inline-block;
height: 100%;
width: 0;
vertical-align: middle;
}
.layerdiv-inline .tips{
position: relative;
background: #dedada;
box-shadow: 0 3px 6px #f00;
display: inline-block;
vertical-align: middle;
}
/*table布局解决方式*/
.layerdiv-table {
width: 100%;
height: 100%;
position: fixed;
z-index: 9999;
/*background: rgba(0,0,0,0.5);*/
display: table;
text-align: center;
}
.layerdiv-table:after {
content: "";
display: inline-block;
height: 100%;
width: 0;
vertical-align: middle;
}
.layerdiv-table .tips{
position: relative;
background: #dedada;
box-shadow: 0 3px 6px #f00;
display: table-cell;
vertical-align: middle;
}
</style>
</head>
<body>
<div class="layerdiv-flex ">
<div class="tips">
<h2>测试文字模糊问题嘿嘿嘿</h2>
<h3>测试文字模糊问题嘿嘿嘿</h3>
<h4>fixed+transform(非整数)</h4>
</div>
</div>
<!-- <div class="layerdiv-inline ">
<div class="tips">
<h2>测试文字模糊问题嘿嘿嘿</h2>
<h3>测试文字模糊问题嘿嘿嘿</h3>
<h4>fixed+transform(非整数)</h4>
</div>
</div>
<div class="layerdiv-table ">
<div class="tips">
<h2>测试文字模糊问题嘿嘿嘿</h2>
<h3>测试文字模糊问题嘿嘿嘿</h3>
<h4>fixed+transform(非整数)</h4>
</div>
</div> -->
<div class="layerdiv">
<h2>测试文字模糊问题嘿嘿嘿</h2>
<h3>测试文字模糊问题嘿嘿嘿</h3>
<h4>fixed+transform(整数)</h4>
</div>
<div class="con">
带滚动条的内容页
</div>
</body>
</html>