共计 2872 个字符,预计需要花费 8 分钟才能阅读完成。
display 和 visbility 顾名思义都是为了暗藏页面元素,上面来看看二者的区别。opacity 最初再说。
一、display:none
1、给元素设置了 display:none 属性后,该元素就暗藏了,占用的空间也隐没了。
原来是这样:
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
</div>
加了 display:none 属性后
<div>
<button>A 按钮 </button>
<button style="display: none">B 按钮 </button>
<button>C 按钮 </button>
</div>
事实证明,“B 按钮”占用的空间也隐没了。
2、给父元素设置 display:none 属性后,子属性也跟着暗藏。
原来的样子:
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
<ol>
<li>hello</li>
<li>hello2</li>
</ol>
</div>
给父元素加上 display:none 后,子元素都隐没了
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
<ol style="display: none">
<li>hello</li>
<li>hello2</li>
</ol>
</div>
即便给子元素加上 block 也不会显示。
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
<ol style="display: none">
<li style="display: block">hello</li>
<li>hello2</li>
</ol>
</div>
3、因为 display:none 后元素就隐没了,在 li 标签下会影响计数。比方
原来的代码:
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
<ol>
<li>hello</li>
<li>hello2</li>
<li>hello3</li>
</ol>
</div>
给子元素加上暗藏:
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
<ol>
<li>hello</li>
<li style="display: none">hello2</li>
<li>hello3</li>
</ol>
</div>
因为子元素被暗藏了,上面的元素就主动上移了。
二、visibility:hidden
1、应用 visibility 暗藏属性后,元素依然占用原来的页面空间。
<div>
<button>A 按钮 </button>
<button style="visibility: hidden">B 按钮 </button>
<button>C 按钮 </button>
</div>
暗藏后
2、父元素会影响子元素,以及如果子元素设置显示后,会打消暗藏属性。
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
<ol style="visibility: hidden">
<li>hello</li>
<li>hello2</li>
<li>hello3</li>
</ol>
</div>
<div>
<button>A 按钮 </button>
<button>B 按钮 </button>
<button>C 按钮 </button>
<ol style="visibility: hidden">
<li>hello</li>
<li style="visibility: visible">hello2</li>
<li>hello3</li>
</ol>
</div>
由此可见,第三点,visibility 也不会影响计算,只是给暗藏的那些元素披上了隐身衣而已,不会影响别的元素。
最初一点:
首先理解下浏览器的渲染过程:
1. 解析 HTML,依据文档构建 DOM 树
2. 解析 CSS 样式表,构建 CSSOM(CSS Object Model)
3. 将 DOM 和 CSSOM 进行合并生成 Render Tree(渲染树);在 DOM 树根底上依据节点的属性(margin/padding/width/height)生成 reder 树,不包含 display:none、head 节点但包含 visibility:hidden 节点)
4. 依据 Render Tree 计算布局,计算每个元素的地位,又叫 layout 的 reflow 过程
5. 根据 Render Tree 进行渲染,调用操作系统的 Native GUI 的 API 绘制。
其次理解两个概念,重绘和回流
1. 重绘(repoint): 当 Render Tree 中的一些元素须要更新属性,但这些属性只会影响元素的外观,格调,而不会影响布局。
2. 回流(reflow):当 Render Tree 中的一部分(或所有) 因为其中元素的规模尺寸、布局、暗藏等扭转而须要从新构建 Render Tree。
因为 display:none 会扭转页面布局,所以会触发 reflow(回流),而 visibility:hidden 并不影响 页面布局,只是给元素穿上了“隐身衣”,所以只会触发 repoint(重绘)
总结:
(上面 display:none 就简写为 display,visibility:hidden 就简写为 visibility)
1)display 的暗藏会间接把元素去掉,其占用的空间也隐没;visibility 相同,只是给暗藏的元素穿了层“隐身衣”,其占用的空间并不会隐没。
2)display 父元素设置为暗藏后子元素也会暗藏,然而子元素若设置为显示并不见效;
visibility 父元素暗藏子元素暗藏,父元素暗藏子元素显示会见效。
3) display 因为间接把元素去掉了,所以会影响计数,比方下面例子里的 li 标签,就上面的元素主动替补被暗藏的元素了。visibility 因为只是单纯的暗藏,所以不会影响计数。
4)因为 display 影响页面布局,所以会触发 reflow(回流),visibility 则只会触发 repoint(重绘)。
一言半语汇成一句话
就是 display 把一个元素丢出界面,所以空间会隐没、别的元素会替补以及触发回流(从新布局)。而 visibility 只是给元素穿了个“隐身衣”,所以其空间还在、不会影响计数、只会触发重绘(布局不变,然而要减少“隐身衣”成果。)
补充:其实还有个办法能够暗藏元素,那就是 opacity:0,这个属性是设置透明度的,取值范畴是 0 -1,设置为 0 就是暗藏了,1 就是齐全显示,这个办法和 visibility 的特质一样,简而言之就是给元素穿了隐身衣而已。
参考文章:
浏览器的渲染原理简介:https://coolshell.cn/articles…