zoukankan      html  css  js  c++  java
  • 关于opacity、visibility、display属性的一道CSS面试题

    https://blog.csdn.net/FE_dev/article/details/72628734

    问题:
    一个下拉菜单,结构如下,

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <style>
    div{
    400px;
    height:40px;
    background:red;
    position:relative;
    }
    div ul{
    position:absolute;
    top:0;
    left:0;
    200px;
    height:300px;
    background:yellow;
    }
    p{
    200px;
    height:200px;
    background:blue;
    }
    </style>
    </head>
    <body>
    <div>
    <ul>
    <li>菜单一</li>
    <li>菜单二</li>
    <li>菜单三</li>
    </ul>
    </div>

    <p onmouseenter=alert(0)></p>
    </body>
    </html>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    鼠标移入div,显示菜单ul,移出后隐藏菜单ul,只使用CSS,如何实现既有淡入淡出的效果,而又不影响其他元素,不产生回流?

    实现
    这个问题,看上去似乎很简单,有些同学一定会想到,加透明度就能就解决,来看下是不是。

    代码

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <style>
    /* 红色块 div */
    div{
    400px;
    height:40px;
    background:red;
    position:relative;
    }
    /* 黄色块 ul */
    div ul{
    position:absolute; /* 菜单ul绝对定位 */
    top:0;
    left:0;
    200px;
    height:300px;
    background:yellow;
    opacity:0; /* 开始透明度为0 */
    transition:opacity .5s; /* 0.5s完成 透明度0-1的变化 */
    }
    /* 蓝色块 p */
    p{
    200px;
    height:200px;
    background:blue;
    }
    div:hover ul{
    opacity:1; /* 鼠标进入div,ul的透明度从0过渡到1 */
    }
    </style>
    </head>
    <body>
    <div>
    <ul>
    <li>菜单一</li>
    <li>菜单二</li>
    <li>菜单三</li>
    </ul>
    </div>

    <p onmouseenter=alert(0)></p>
    </body>
    </html>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    效果图


    明显,并没有达到我们需要的效果,当鼠标进入蓝色块的时候,没有触发绑定的事件,而是把菜单显示出来了,这已经是很大的影响了,这主要是因为,opacity属性只是改变透明度,并不是真的让这个元素消失。

    说到这,你也许会想到用display属性,但是不可以,首先,display不支持过渡,也就是说,用了他,淡入淡出的效果就没有了,而且他还会产生会回流和重绘,所以这里,我们给他用 visibility 属性就可以了,visibility 属性,支持过渡,而且不会产生回流,虽然 visibility=hidden; 会占据页面空间,但是并不影响其他元素的事件触发和显示。

    代码

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <style>
    /* 红色块 div */
    div{
    400px;
    height:40px;
    background:red;
    position:relative;
    }
    /* 黄色块 ul */
    div ul{
    position:absolute; /* 菜单ul绝对定位 */
    top:0;
    left:0;
    200px;
    height:300px;
    background:yellow;
    opacity:0; /* 开始透明度为0 */
    transition:opacity .5s; /* 0.5s完成 透明度0-1的变化 */

    visibility:hidden; /* 增加 */
    }
    /* 蓝色块 p */
    p{
    200px;
    height:200px;
    background:blue;
    }
    div:hover ul{
    opacity:1; /* 鼠标进入div,ul的透明度从0过渡到1 */

    visibility:visible; /* 增加 */
    }
    </style>
    </head>
    <body>
    <div>
    <ul>
    <li>菜单一</li>
    <li>菜单二</li>
    <li>菜单三</li>
    </ul>
    </div>

    <p onmouseenter=alert(0)></p>
    </body>
    </html>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    效果图


    这样我们就实现了,需要的效果。

    对比分析
    问题解决了,我们来分析一下,opacity、display、visibility这三个属性。
    说之前,我们先讲两个概念,回流和重绘。

    回流

    当页面中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(也有人会把回流叫做是重布局或者重排 )。每个页面至少需要一次回流,就是在页面第一次加载的时候。

    重绘

    当页面中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的时候,比如background-color。则称为重绘。

    注意:回流必将引起重绘,而重绘不一定会引起回流。


    从图中应该能很清楚看出,他们之间的区别了,要注意的是:
    visibility支持过渡
    visibility属性虽然支持过渡,但是,不是平滑的过渡,而是进行了一个延时,并且它只是 从 visible 过渡 到 hidden 有延迟,从 hidden 过渡到 visible 不延迟,如图

    透明度(opacity)不会触发重绘

    实际上透明度改变后,GPU在绘画时只是简单的降低之前已经画好的纹理的alpha值来达到效果,并不需要整体的重绘。不过这个前提是这个被修改 opacity 本身必须是一个图层,如果图层下还有其他节点,GPU也会将他们透明化

    总结
    最开始的问题,一般是会出现在做一些鼠标悬停特效的时候,鼠标悬停,出现一个div,或者img,而这些元素刚开始是看不见的,他们定位在页面上,如果他们只是透明度发什么变化,很有可能,影响到其他的元素不能触发事件。

    简单理解就像,一个a,上面有一个div,div的透明度为0,那么a就无法跳转了,div虽然看不见,但是还是存在的,挡住了a,感觉就像是a上面有一块玻璃,挡住了他。要解决问题,就要给div用上visibility属性。

    这篇文章重点还是说最开始提到的那个问题,而对于 opacity、visibility、display 这三个属性并没有进行非常详细的对比分析,所以后来又写了一篇文章。
    CSS中用 opacity、visibility、display 属性将 元素隐藏 的 对比分析
    ---------------------
    作者:FEWY
    来源:CSDN
    原文:https://blog.csdn.net/FE_dev/article/details/72628734
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    数据结构和算法
    Java Zip工具类(全)
    Java Zip压缩文件返回前端并下载
    Java 通过URL进行远程文件下载
    最通俗易懂的JavaScript实用案例
    通俗易懂的JavaScript进阶教程
    最通俗易懂的JavaScript入门教程
    Git和Github详细入门教程(别再跟我说你不会Git和Github)
    HTML入门详细总结
    你好,我是梦阳辰!
  • 原文地址:https://www.cnblogs.com/beimingbingpo/p/9834864.html
Copyright © 2011-2022 走看看