这篇文章发布于 2015年01月10日,星期六,02:38,归类于 CSS相关。 阅读 56364 次, 今日 4 次 22 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=4536
一、Chrome虽好,可别贪杯哦~
一般我们对Chrome浏览器的评价是:Chrome好棒!Chrome好潮!Chrome就是多来A梦,要什么有什么!
但是,再好的奶茶也会有过期的时候。很多次遇到,Chrome下的渲染表现是最糟糕的那个。比方说,在transform
内部做CSS3 animation
动画,Chrome会让文字一会儿粗一会儿细,甚至上下跳动,于是我们可以100%确认,这个页面是公的,会CSS3 animation
的挑逗有反应。
嘛,毕竟只是细节上的不爽,睁一只眼闭一只眼也就过去了。但是,有些影响布局的bug可就没法视而不见了。你可能会惊讶:“纳尼!Chrome这么好的浏览器有bug, 会不会是你看错了?”
虽说Chrome是你见过的最单纯的姑娘,但是,真正相处久了,终究会发现,如果真的足够纯,就不叫奶茶了。
我这里给大家展示两个Chrome absolute
绝对定位引发的渲染bug, 这些bug已经历经很多代(写本文时候使用Chrome版本是40)都没有修复了,跟我来~
二、Chrome下absolute绝对定位元素部分display属性值不渲染bug
此bug描述如下:
Chrome浏览器下,绝对定位元素,其
display
值在inline/inline-block
和block
之间切换时候,是不重新渲染的。
百闻不如一见,您可以狠狠地点击这里:Chrome浏览器下绝对定位元素display渲染bug demo
我们进入demo,首先引入眼帘的是这个样子(张小姐抹白是为了节约至少60%图片尺寸大小,下同):
此时,图片没有任何display
设置,是默认的inline-block
水平。要知道,元素absolute
绝对定位,如果没有left/top等值,位置是不移动的(可参考我很多年前写的“CSS 相对/绝对(relative/absolute)定位系列(二)”一文),因此,紧随文字显示是没有任何问题的。
但是,当我们点击左边这个按钮,修改图片的display
水平为block
,尼玛图片居然还傻不拉几呆在后面,而且就Chrome浏览器是这样,IE8+以及Firefox之流①都是萌萌哒换行显示:
//zxx: IE7也不会换行,但那是解析bug;而这里Chrome是不渲染bug~
如何修复此bug?
2年前的这个时候,我曾写过一篇文章:“利用重绘解决IE下JS交互产生的定位重叠等棘手bug”,可谓前端从业必读基础技能文章。
用一句话概述为就是:“遇到一些交互渲染bug时候,不妨触发浏览器的重绘,说不定问题即解决。”
这里Chrome不渲染bug修复中心思想也是一样的,就是触发重绘。但是,术业有专攻,代码有小受。上文中抛出来的visibility:inherit/visible
切换方法在Chrome这里是没有效果滴!“我了个擦,这是要闹哪样?” 稍安勿躁,上帝关上了一扇门,那我们就换一个门出去。
这里隆重推出新时代webkit/blink内核渲染bug修复神器,业界俗称webkit届haslayout的东西:-webkit-transform: translateZ(0);
肉眼看上去,此申明对页面元素不会有什么影响;但是,好比老IE时代的zoom: 1
。灭虫能力堪比敌敌畏!
我们回到demo,注意右侧蓝色按钮,对,就是那个含有“同时toggle translateZ”字样的按钮,此按钮是干嘛的呢?就是触发左侧按钮点击同时,给图片父级toggle切换translateZ(0)
属性值,如下截图:
结果,图片正常渲染咯!——换行,跟随,换行,跟随,…… 好棒!
三、Chrome下absolute绝对定位元素具有overflow属性的块状子元素visibility hover不渲染bug
此bug具体描述如下:
Chrome浏览器下,绝对定位元素,同时visibility:hidden时候,如果子元素具有块状水平,同时设置了overflow:hidden; 则父元素hover时候,无法让子元素visibility:visible渲染生效!
百闻不如一见,您可以狠狠地点击这里:Chrome浏览器下绝对定位元素visibility渲染bug demo
我们先看HTML代码:
<div class="hover"> Chrome罕见visibility渲染bug(<em>hover me</em>) <div class="abs_vh"> <div id="bug" class="bug"><img src="mm1.jpg"></div> </div> </div>
然后CSS代码:
.abs_vh { position: absolute; visibility: hidden; } .bug { overflow: hidden; /* 重要条件 */ } .hover:hover .bug { visibility: visible; /* Chrome浏览器下,此声明无效 */ }
可以看到,HTML结构超级简单,CSS更是简单,总共就出现了4个CSS声明,但是,就是且必须这4个声明同时存在的时候,bug才会出现。
回到demo,我们hover demo页面文字,结果Chrome浏览器下,没有任何反应:
而爱意之流,火狐之流却风生水起:
由于一般人不会用到visibility
的recover重置特性(类似还有cursor
)(差不多3年前“您可能不知道的CSS元素隐藏‘失效’以其妙用”一文有介绍过visibility这个特性),因此,此bug几乎很难重现。
如何修复此bug?
我就不卖关子了,修复此bug的关键就是上面吹嘘过的神器,被誉为webkit界中的haslayout:-webkit-transform: translateZ(0);. 在需要visibility
显示的元素添加这段CSS申明就可以了。
我们回到demo,有个光杆按钮,干嘛用的呢?给.bug
这个元素toggle -webkit-transform: translateZ(0)
这个声明。例如,我们点击下这个按钮,然后再去hover文字:
哦!!!小妹子图片显示出来了!好棒!
demo本着演示目的,在JS内联,实际上,要修复,CSS足矣,如下:
然后CSS代码:
.abs_vh {
position: absolute; visibility: hidden;
}
.bug {
overflow: hidden;
}
.hover:hover .bug {
visibility: visible;
-webkit-transform: translateZ(0); /* 没错,靠的就是你!*/
}
由于上面两个bug都是来自Chrome,所以,神器使用了私有前缀,既不会影响其他OK浏览器,也似乎在大声表明:我就是hack,我就是补丁!
四、酒不醉人人自醉,结语写完就去睡
Chrome渲染的些bug自然不止本文这两个,主要是本文bug都由绝对定位absolute引发(可能高效渲染计算设计导致),然后都可以-webkit-transform: translateZ(0)
修复,因此就放在一起讲了。
记得以前似乎见到过浮动随机渲染的bug;去年做iOS原型时候遇到过过场渲染的bug(夜太深,具体我记不清了),也是使用translateZ
修复的。所以,如果大伙儿在折腾webkit内核页面时候,遇到奇怪渲染问题,都可以试试webkit界的haslayout, 渲染问题修复神器-webkit-transform: translateZ(0),说不定会有好运降临!
技术不止,进步不断,说不定下个版本问题就会被修复,到时,还希望广大同学提个醒,我好及时更新。
感谢阅读,有任何问题都欢迎交流!
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4536
(本篇完)
- 直线等图形3D穿过文字的CSS实现 (0.356)
- 利用重绘解决IE下JS交互产生的定位重叠等棘手bug (0.302)
- pointer-events:none提高页面滚动时候的绘制性能? (0.215)
- 使用CSS3 will-change提高页面滚动、动画等渲染性能 (0.184)
- 小tip: 微博新版查看大图前后浏览的另外一种实现 (0.154)
- display:inline-block/text-align:justify下列表的两端对齐布局 (0.143)
- 去除inline-block元素间间距的N种方法 (0.143)
- CSS深入理解流体特性和BFC特性下多栏自适应布局 (0.143)
- CSS深入理解vertical-align和line-height的基友关系 (0.143)
- IE6下z-index犯癫不起作用bug的初步研究 (0.143)
- 回流与重绘:CSS性能让JavaScript变慢? (RANDOM - 0.119)
新版还存在的BUG,当前文章页面运行一下代码可以重现!
var div = document.createElement(“div”);
div.style.backgroundColor=”#f00″;
div.style.position=”absolute”;
div.style.width = “200px”;
div.style.height = “200px”;
div.style.left = “200px”;
div.style.bottom = “50%”; //如果bottom属性换成top则没有此bug
document.body.appendChild(div); //此时发现位置并非正确,如果body设置了relative也没有此bug
document.body.style.transform=”translateZ(0)”; //神奇的解决了
这几个bug都解决了
我的版本是59
今天也碰到chrome不重新渲染的bug了,不过不是display的,是关于 position 切换成 fixed 时,也出现了不重新渲染的情况。。。最后也是添加了一个 translateZ(0) 解决。。。。
css3动画时,只要是x,y位移动画,例如: -webkit-transform: translateY(-500px); 会导致动画结束后大约有200ms-500ms不等的时间延迟,此时动画的元素上的鼠标事件全部不能响应,有没有同学遇到过同样问题,其它浏览器均正常!!!
补充:在同样使用webkit内核的浏览器上如opera,safari均是正常的。。。
我发现的chrome bug是在定位后背景png图片出现一个大白块,-webkit-transform: translateZ(0);无效,最后是用js让他display:none,然后sildeDown。。。。。
我也遇到了元素绝对定位显隐时的重叠问题。是在mac下的,刚开始用display block/hide显隐,但有问题,又换了visibility,貌似是解决了问题,过两天又发现当同级元素不够多,未排满一行的时候(这个不好描述)还是有问题,想到应该是需要让元素重绘或者内容区重新渲染,然后就无意间找到此文,bug就立马解决了,”业界良心”啊,哈哈,点赞
你好,最近遇到一个hover改变层级的问题,在chrome下hover会有闪烁,但是ff是正常的。
我的代码:
#f {
width: 200px;
height: 200px;
background-color: red;
position: absolute;
z-index: 0;
-webkit-transform: translateZ(0);
}
#f:hover {
z-index: -2;
-webkit-transform: translateZ(0);
}
#s {
width: 200px;
height: 200px;
background-color: black;
position: absolute;
z-index: -1;
-webkit-transform: translateZ(0);
}
#s:hover {
z-index: 0;
-webkit-transform: translateZ(0);
}
1
2
@bby 你好,建议去http://jsbin.com或http://jsfiddle.net弄一个在线Demo, 有助于提高沟通效率。
厉害!我也定位到是position影响 的页面无法重绘,但是没想到这么好的解决方案,举一反三,碰到类似的再也不慌了,关注你博客许久,非常感谢!
已捐赠,加油!
旭哥,慕课上的《CSS深入理解之absolute》怎么不更新了啊?期待好久了,求更新
@WingMeng 你好,全系列早在数月前就交付了。可能慕课网现在课程较多,所以更新有点慢。
换个名称看看怎么样(Stone)
路过打酱油的~~
额 弱弱的问一下 这个博客提交评论的部分是通过邮件和名称去匹配用户的吗??邮件相当于密码??
那个,张鑫旭前辈,`position: absolute`会导致元素的display计算值是block,无论display原来的值是什么……个人觉得不算bug……
@Humphry 你好,说的不是一个事~
是这样的,对于position: absolute元素来说,无论其display为inline-block还是block,最终display的计算值为block(见http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo : Otherwise, if ‘position’ has the value ‘absolute’ or ‘fixed’, the box is absolutely positioned, the computed value of ‘float’ is ‘none’, and display is set according to the table below. The position of the box will be determined by the ‘top’, ‘right’, ‘bottom’ and ‘left’ properties and the box’s containing block.)。这样的话,在display从block到inline-block的切换中,并不会影响元素的布局模型,因此我认为依靠改变display属性来强制position: absolute元素重绘不太合适。
@Humphry 你好,按照规范,元素绝对定位后,原本位置是不变的。我们说的不是一个事。
元素绝对定位以后,display就当作block来计算了,改变其display属性为block,并没有计算值的变化,不重绘也没有问题。这是我的point……
测试了一下,scale(1),skew(0),rotate(0)都可以,这些都是触发了硬件加速么?
@xiaowtz 可能哦,若有兴趣,可以研究下~
Chrome快是快,不过牺牲的就是渲染质量,(相对于FF和IE)。以前遇到过CSS3动画的时候,Chrome会明显比其余两者慢。
额,我本来想说两句话,然后后面一句前面应该加上转折过渡的词语。