Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 57 题:分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景 #100

Open
zeroone001 opened this issue Apr 17, 2019 · 21 comments

Comments

@zeroone001
Copy link

zeroone001 commented Apr 17, 2019

  1. display: none (不占空间,不能点击)(场景,显示出原来这里不存在的结构)
  2. visibility: hidden(占据空间,不能点击)(场景:显示不会导致页面结构发生变动,不会撑开)
  3. opacity: 0(占据空间,可以点击)(场景:可以跟transition搭配)
@bigmeow
Copy link

bigmeow commented Apr 18, 2019

补充: opacity 场景: 自定义图片上传按钮

@zhengyeye
Copy link

补充:株连性
如果祖先元素遭遇某祸害,则其子孙孙无一例外也要遭殃,比如:
opacity:0和display:none,若父节点元素应用了opacity:0和display:none,无论其子孙元素如何挣扎都不会再出现在大众视野;
而若父节点元素应用visibility:hidden,子孙元素应用visibility:visible,那么其就会毫无意外的显现出来。

@neofanfei
Copy link

display: none 会回流操作 性能开销较大,
visibility: hidden 是重回操作 比回流操作性能高一些,(回流会计算相邻元素甚至组先级元素的位置,属性等)
opacity: 0 重建图层,性能较高

@Rashomon511
Copy link

Rashomon511 commented Apr 18, 2019

总结一下:
结构:
display:none: 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击,
visibility: hidden:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击
opacity: 0: 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击

继承:
display: none和opacity: 0:是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。
visibility: hidden:是继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。

性能:
displaynone : 修改元素会造成文档回流,读屏器不会读取display: none元素内容,性能消耗较大
visibility:hidden: 修改元素只会造成本元素的重绘,性能消耗较少读屏器读取visibility: hidden元素内容
opacity: 0 : 修改元素会造成重绘,性能消耗较少

联系:它们都能让元素不可见

@zaviertang
Copy link

  • display: none;
  1. DOM 结构:浏览器不会渲染 display 属性为 none 的元素,不占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性能:动态改变此属性时会引起重排,性能较差;
  4. 继承:不会被子元素继承,毕竟子类也不会被渲染;
  5. transitiontransition 不支持 display
  • visibility: hidden;
  1. DOM 结构:元素被隐藏,但是会被渲染不会消失,占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性 能:动态改变此属性时会引起重绘,性能较高;
  4. 继 承:会被子元素继承,子元素可以通过设置 visibility: visible; 来取消隐藏;
  5. transitiontransition 不支持 display
  • opacity: 0;
  1. DOM 结构:透明度为 100%,元素隐藏,占据空间;
  2. 事件监听:可以进行 DOM 事件监听;
  3. 性 能:提升为合成层,不会触发重绘,性能较高;
  4. 继 承:会被子元素继承,且,子元素并不能通过 opacity: 1 来取消隐藏;
  5. transitiontransition 不支持 opacity

@superermiao
Copy link

display:none指的是元素完全不陈列出来,不占据空间,涉及到了DOM结构,故产生reflow与repaint。

visibility:hidden指的是元素不可见但存在,保留空间,不影响结构,故只产生repaint(脱离文档流),子元素可以通过设置 visibility: visible; 来取消隐藏;

opacity: 0:透明度为 100%,元素仍存在,不影响结构,不和动画属性一起则不会产生repaint(不脱离文档流),子元素并不能通过 opacity: 1 来取消隐藏;

@MKLM0222
Copy link

visibility:hidden 隐藏元素,但是元素本身还是存在的
display: none 元素是不占据空间,
opacity: 0 透明度为 100%

@Rashomon511
Copy link

总结一下:
结构:
display:none: 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击,
visibility: hidden:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击
opacity: 0: 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击
继承:
display: none和opacity: 0:是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。
visibility: hidden:是继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。
性能:
displaynone : 修改元素会造成文档回流,读屏器不会读取display: none元素内容,性能消耗较大
visibility:hidden: 修改元素只会造成本元素的重绘,性能消耗较少读屏器读取visibility: hidden元素内容
opacity: 0 : 修改元素会造成重绘,性能消耗较少
联系:它们都能让元素不可见

visibility: hidden; 不可以点击,拼写错了吧。

是的,该过来了

@webXLing
Copy link

总结下

display:none: dom根本不生成 不占据空间 子元素会被株连 重新设置 会引发重绘 和 回流
visibility:hidden dom生成 占据空间 但是 不可以点击 不可见 重设会引发重绘 子元素可以动过设置visible设置为可见
opacity:0; dom生成 占据空间 只是透明度为0 不可见 可以点击 重设会引发重绘 子元素可以动过设置1设置为可见

@liuyanxing
Copy link

display: none 会回流操作 性能开销较大,
visibility: hidden 是重回操作 比回流操作性能高一些,(回流会计算相邻元素甚至组先级元素的位置,属性等)
opacity: 0 重建图层,性能较高

浏览器在渲染的时候生成的layout tree并不会包含display:none的元素,为什么还会引起回流呢

@BosenY
Copy link

BosenY commented Jul 31, 2019

补充:
display: none; 如果应用在了某个SEO场景,是会判SEO作弊的,这个要注意

@zhiweiweii
Copy link

1、display: none 触发回流,消耗性能较大
2、visibility: hidden 触发重绘,消耗性能较1少
3、opacity: 0 css3硬件加速,不触发回流重绘,大大减少性能消耗

@yywc
Copy link

yywc commented Aug 8, 2019

  • display: none;
  1. DOM 结构:浏览器不会渲染 display 属性为 none 的元素,不占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性能:动态改变此属性时会引起重排,性能较差;
  4. 继承:不会被子元素继承,毕竟子类也不会被渲染;
  5. transitiontransition 不支持 display
  • visibility: hidden;
  1. DOM 结构:元素被隐藏,但是会被渲染不会消失,占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性 能:动态改变此属性时会引起重绘,性能较高;
  4. 继 承:会被子元素继承,子元素可以通过设置 visibility: visible; 来取消隐藏;
  5. transitiontransition 不支持 display
  • opacity: 0;
  1. DOM 结构:透明度为 100%,元素隐藏,占据空间;
  2. 事件监听:可以进行 DOM 事件监听;
  3. 性 能:提升为合成层,不会触发重绘,性能较高;
  4. 继 承:会被子元素继承,且,子元素并不能通过 opacity: 1 来取消隐藏;
  5. transitiontransition 不支持 opacity

transition 是支持 visibility 和 opacity 的噢,CSS animated properties可查。

  • visibility 会立即显示,隐藏时会延时
  • opacity 可以延时显示和隐藏

@tangbc
Copy link

tangbc commented Aug 23, 2019

问:用 CSS 隐藏页面上的一个元素有哪几种方法?

这道题绝大多数人的答案都是 display:none visibility:hiden opacity:0 这三种,但如果还能说出下面三种我觉得也是加分的:

  1. 设置 fixed 并设置足够大负距离的 left top 使其“隐藏”;
  2. 用层叠关系 z-index 把元素叠在最底下使其“隐藏”;
  3. text-indent:-9999px 使其文字隐藏。

@TongMonkey
Copy link

适用场景呢

@Jmingzi
Copy link

Jmingzi commented Nov 21, 2019

我觉得上面关于 opacity 重绘说的都有问题。所以来总结下:

  • 在一般情况下,opacity 会触发重绘,即 Recalculate style => Update Layer Tree。不管你是否开启GPU提升为合成层与否
  • 如果利用 animation 动画,对 opacity 做变化(animation会默认触发GPU加速),则只会触发 GPU 层面的 composite,不会触发重绘。

以上可以使用 performance 验证!!!

@zuoyi615
Copy link

打个比方

  1. display: none 从这个世界消失了, 不存在了
  2. opacity: 0 视觉上隐身了, 看不见, 可以触摸得到
  3. visibility: hidden; 视觉和物理上都隐身了, 看不见也摸不到, 但是存在的

@youngs-github
Copy link

补充一点,使用ol+li计数时,display:none是不参与计数的,而visibility:hidden参与计数

@Chorer
Copy link

Chorer commented Apr 13, 2021

display: none 会回流操作 性能开销较大,
visibility: hidden 是重回操作 比回流操作性能高一些,(回流会计算相邻元素甚至组先级元素的位置,属性等)
opacity: 0 重建图层,性能较高

浏览器在渲染的时候生成的layout tree并不会包含display:none的元素,为什么还会引起回流呢

他说的容易引起歧义。准确地说应该是给元素设置 display: none 之后,会导致元素脱离布局树,触发重排。如果元素本身就是 display: none 了,那么针对它的其它操作不会再触发重排。

@shifengdiy
Copy link

三种情况各有其使用场景,重点区别在于两点,

  1. visibility:hidden元素无法使用事件监听,而同为opacity: 0可以使用事件
  2. visibility: hidden元素具有继承属性,子元素使用 visibility: visible就是可以让元素展示

@lzyaom
Copy link

lzyaom commented Sep 27, 2021

  • display: none;
  1. DOM 结构:浏览器不会渲染 display 属性为 none 的元素,不占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性能:动态改变此属性时会引起重排,性能较差;
  4. 继承:不会被子元素继承,毕竟子类也不会被渲染;
  5. transitiontransition 不支持 display
  • visibility: hidden;
  1. DOM 结构:元素被隐藏,但是会被渲染不会消失,占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性 能:动态改变此属性时会引起重绘,性能较高;
  4. 继 承:会被子元素继承,子元素可以通过设置 visibility: visible; 来取消隐藏;
  5. transitiontransition 不支持 display
  • opacity: 0;
  1. DOM 结构:透明度为 100%,元素隐藏,占据空间;
  2. 事件监听:可以进行 DOM 事件监听;
  3. 性 能:提升为合成层,不会触发重绘,性能较高;
  4. 继 承:会被子元素继承,且,子元素并不能通过 opacity: 1 来取消隐藏;
  5. transitiontransition 不支持 opacity

opacity: 0不会被子元素继承

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests