先把css隐藏页面元素有几种方法列出来,方便查看以及使用,下文再分析其中的原理
- display : none ; /* 不占据空间,无法点击 */
- opacity: 0; filter:Alpha(opacity=0); /* 占据空间,可以点击 */
- visibility: hidden; /* 占据空间,无法点击 */
- height: 0; overflow: hidden; /* 不占据空间,无法点击 */
- position: absolute; top: -999em; /* 不占据空间,无法点击 */
另外我还看到张鑫旭大神博客里面还有写着其他几种方法
- position: relative; top: -999em; /* 占据空间,无法点击 */
- position: absolute; opacity: 0; filter:Alpha(opacity=0); /* 不占据空间,可以点击 */
- zoom: 0.001;
-moz-transform: scale(0);
-webkit-transform: scale(0);
-o-transform: scale(0);
transform: scale(0);
/* IE6/IE7/IE9不占据空间,IE8/FireFox/Chrome/Opera占据空间。都无法点击 */
- position: absolute;
zoom: 0.001;
-moz-transform: scale(0);
-webkit-transform: scale(0);
-o-transform: scale(0);
transform: scale(0);
/* 不占据空间,无法点击 */
欢迎补充!
既然有这么多的效果,那为什么不直接统一一个标准来执行,简洁了事。可是想想,它们看起来都实现着隐藏的效果,但是每一种方法与其他方法之间都有一些的不同,这些不同决定了在一个特定的场合下使用哪一个方法。所以写这篇文章的原因就是把这些隐藏的方法总结一下,方便以后翻阅使用。
Display
display属性依照词义真正隐藏元素。将 display属性设为 none 确保元素不可见并且连盒模型也不生成。使用这个属性,被隐藏的元素不占据任何空间。不仅如此,一旦 display设为none任何对该元素直接打用户交互操作都不可能生效。此外,读屏软件也不会读到元素的内容。这种方式产生的效果就像元素完全不存在。任何这个元素的子孙元素也会被同时隐藏 -- 也就是【“株连性”】,下文会有讲解。为这个属性添加过渡动画是无效的,它的任何不同状态值之间的切换总是会立即生效。
不过请注意,通过 DOM 依然可以访问到这个元素。因此你可以通过 DOM 来操作它,就像操作其他的元素。
Opacity
opacity属性的意思是设置一个元素的透明度。它不是为改变元素的边界框(bounding box)而设计的。这意味着将 opacity 设为 0 只能从视觉上隐藏元素。而元素本身依然占据它自己的位置并对网页的布局起作用。它也将响应用户交互。如果在IE8以下浏览器 需要添加滤镜才能添加透明,另外可以阅读之前文章《IE7透明度兼容》。
Visibility
visibilitys属性它的值设为 hidden将隐藏我们的元素。如同opacity属性,被隐藏的元素依然会对我们的网页布局起作用。与 opacity 唯一不同的是它不会响应任何用户交互。此外,元素在读屏软件中也会被隐藏。
这个属性也能够实现动画效果,只要它的初始和结束状态不一样。这确保了 visibility 状态切换之间的过渡动画可以是时间平滑的(事实上可以用这一点来用 hidden 实现元素的延迟显示和隐藏——译者注)。
.hide { visibility: hidden;}
我原本以为元素使用Visibility:hidden之后,使用Opacity:1或者jQuery的 fadeIn()荡入效果可以使元素显示出来,可是使用jquery的animate时候,鼠标经过将隐藏元素设置为Opacity:1的时候,浏览器提出了“opacity is not defined”的报告。。。
使用第二种fadeIn(),鼠标经过触发元素的时候,浏览器没有报错,隐藏元素会自动加上 display:block ;可是隐藏元素还是没有显示出来。。。
后来翻了一下资料, visibility是这样定义的: visibility属性规定元素是否可见。
而我所做的Opacity:1或者jQuery的 fadeIn()都是对透明度的操作。
由此可见在这个情况下,“可见” 与 “透明” 完全不搭边。
Position
假设有一个元素你想要与它交互,但是你又不想让它影响你的网页布局,没有合适的属性可以处理这种情况(opacity 和 visibility 影响布局, display 不影响布局但又无法直接交互)。在这种情况下,你只能考虑将元素移出可视区域。这个办法既不会影响布局,又能让元素保持可以操作。
但Position这个属性用起来会相对复杂一点,因为父级要设置为相对定位,再而将要设置的元素添加绝对定位,
下面是采用这种办法的 CSS:
.hide { position: absolute; top: -9999px; left: -9999px;}
这里的top right bottom left数值还是看项目的需求,这里附上前期完成项目用到的
项目实例
这种方法的主要原理是通过将元素的 top 和 left 设置成足够大的负数,使它在屏幕上不可见。采用这个技术的一个好处(或者潜在的缺点)是用它隐藏的元素的内容可以被读屏软件读取。这完全可以理解,是因为你只是将元素移到可视区域外面让用户无法看到它,而且也方便进行交互,效果实现起来感觉还不错。。。
但是你得避免使用这个方法去隐藏任何可以获得焦点的元素,因为如果那么做,当用户让那个元素获得焦点时,会导致一个不可预料的焦点切换。这个方法在创建自定义复选框和单选按钮时经常被使用。(用 DOM 模拟复选框和单选按钮,但用这个方法隐藏真正的 checkbox 和 radio 元素来“接收”焦点切换——译者注)
display:none和visibility:hidden
在张大神博客看到这两者的不同,主要是下面这三个:
空间占据
回流与渲染
株连性
第一点:这个好理解;
第二点:display:none 隐藏产生reflow和repaint(回流与重绘),而visibility:hidden 没有这个影响前端性能的问题;
第三点:就是“株连性”方面的差异,所谓“株连性”就是父元素设置了隐藏属性,其子元素都会被隐藏。
参照下面代码的栗子
ID为Odiv1的div如果设置了display:none或者visibility:hidden,那么其子元素都会被隐藏掉,一个都不放过,想想好惨T T。
如果 id="Odiv1"设置为visibility:hidden ,其中有个子元素比较调皮, " .tiaopi ”设置了 visibility:visible 那么奇迹发生了,这个元素单独显示出来而其他元素还是老老实实被隐藏掉;
可是display:none用同样的做法,却无效T T,连个机会都不给。。。
可能是这两个属性的“株连性”也有强弱一面(强弱这两个词不知道这样讲对不对)
<div id="Odiv1">
<div id="hide tiaopi">我要被隐藏啦~~~</div>
<div id="hide">我要被隐藏啦~~~</div>
<div id="hide">我要被隐藏啦~~~</div>
</div>
张大神对比总结很生动形象:
display:none是个相当惨无人道的声明,子孙后代全部搞死(株连性),而且连块安葬的地方都不留(不留空间),导致全体民众哗然(渲染与回流)。
visibility:hidden则具有人道主义关怀,虽然不得已搞死子孙,但是子孙可以通过一定手段避免(伪株连性),而且死后全尸,墓地俱全(占据空间),国内民众比较淡然(无渲染与回流)。
height:0和overflow:hidden的组合
这两个结合其实也是一个挺不错的想法,但是在元素未知高度的情况下,交互操作起来相对会麻烦一些。可以看一下我前面的文章《animate使用height:auto无效果》
height:0和overflow:hidden组合隐藏“失效”的条件如下:祖先元素没有position:relative/absolute/fixed声明,同时内部子元素应用了position:absolute/fixed声明。
记住这个:position: absolute元素溢出overflow: hidden元素的时候,如果其第一个含有position属性(static除外)的祖先元素(一直到body)是overflow: hidden元素祖先元素的时候,则不隐藏;否则,隐藏。
参考文章:
1.张鑫旭大师博客
2.众成翻译之“十年踪迹”
3.sitepoint