容易被误解的overflow:hidden
http://www.ofcss.com/2011/03/20/misunderstood-of-overflow-hidden.html(转)
容易被误解的overflow:hidden
为了页面的健壮性,我们常常需要使用overflow:hidden。有时候是为了防止布局被撑开,有时候是为了配合其它规则实现文字截断,还有时候纯粹是为了创建块级上下文。但是,很多人对这个属性是存在着一定的误解的,网上很多入门的资料或文章都只提到用overflow:hidden加固定的宽度(或高度)可以强制隐藏内部的超出容器的内容。包括之前我们在使用overflow:hidden创建块级上下文的方式来实现图文混排时,都认为overflow:hidden造成了特殊情况下的麻烦(详见[cref flexible-two-column-layout-reloaded])。但如果认真阅读一下css规范,会发现overflow:hidden其实并不一定隐藏溢出内容。我之前翻译的[cref clearfix-reloaded-overflowhidden-demystified-translation clearfix改良及overflow:hidden详解]一文中第二部分有讲解,不过可那篇文章的重点是谈清除浮动的问题,所以有关overflow的问题反而没引起注意。
overflow:hidden并不隐藏所有溢出的子元素
对于overflow:hidden的最大误解时:当一个具有高度和宽度中至少一项的容器应用了overflow:hidden时,其内部的任何溢出的内容都将被剪裁(隐藏)。 但事实确实如此吗?答案是“未必”!事实是拥有overflow:hidden样式的块元素内部的元素溢出并不总是被隐藏,具体来说,需要同时满足以下条件:
- 拥有overflow:hidden样式的块元素不具有position:relative和position:absolute样式;
- 内部溢出的元素是通过position:absolute绝对定位; 如果你只关心结论,那么记住这两点就够了。我这里有个demo,结构如下:
<div class="position"> <h2>position box</h2> <div class="overflow"> <h3>overflow box</h3> <div class="static"> <p>This is static child element. This is static child element. This is static child element. This is static child element.</p> <p>This is static child element. This is static child element. This is static child element. This is static child element.</p> </div> <div class="absolute">This is absolute child element. This is absolute child element. This is absolute child element. This is absolute child element.</div> </div> </div> |
我简单截几个图给懒得打开demo的童鞋看一下:


在demo中,你可以看到绝对定位的元素被定位到了overflow:hidden的父元素之外,但是它依然被显示了。而普通元素在水平方向上的溢出被隐藏,垂直方向上撑开父元素。也就是说,普通元素的表现符合我们的预期,而绝对定位元素并不如很多人想当然的那样被隐藏。
理论依据
那么,这个原理到底是什么呢?当然是css2.1规范。在规范中关于overflow的描述中我们可以找到这样一段话:
This property specifies whether content of a block container element is clipped when it overflows the element's box. It affects the clipping of all of the element's content except any descendant elements (and their respective content and descendants) whose containing block is the viewport or an ancestor of the element.
简单翻译一下:
此属性(overflow)规定,当一个块元素容器的内容溢出元素的盒模型边界时是否对其进行剪裁。它(此属性)影响被应用元素的所有内容的剪裁。但如果后代元素的包含块是整个视区(通常指浏览器内容可视区域,可以理解为body)或者是该容器(定义了overflow的元素)的父级元素时,则不受影响。
即使是我重新整理过的语言,还是感觉有点绕。不过在这段话里,出现了一个重要的名词“包含块”(containing block)。包含块是什么呢?这个大家其实比较熟悉,一个绝对定位的元素,其包含块是最近的拥有relative或者absolute定位属性的祖先元素,如果任何一级祖先元素都不符合,则其包含块是body元素(更正:浏览器内容区域)。(2012-09-05: 如果给body元素指定宽高且不指定position:relative,则body也不是绝对定位子元素的包含块。而html元素,即使指定了宽高和position:relative,也只影响绝对定位后代元素的定位,而不能裁剪溢出元素。)
这就说明,一个绝对定位的元素是否被overflow:hidden隐藏,要看其包含块相对于overflow:hidden的位置来决定。这就好比驻日美军,他们不受日本的法律约束而受美国军法约束。因为他们的“包含块”是美国军方而不是日本法院。 实际上在css2.1规范的11.1节,还有更明确的说明:
A descendant box is positioned absolutely, partly outside the box. Such boxes are not always clipped by the overflow property on their ancestors; specifically, they are not clipped by the overflow of any ancestor between themselves and their containing block。
翻译: 一个绝对定位的后代块元素,部分位于容器之外。这样的元素是否剪裁并不总是取决于定义了overflow属性的祖先容器;尤其是不会被位于他们自身和他们的包含块之间的祖先容器的overflow属性剪裁。
回到我的demo,overflow的元素位于相对定位的元素与绝对定位元素之间,因此根据规定它不能剪裁绝对定位的子元素。也就是说爷爷相对定位,老爸规定溢出隐藏,可是儿子是绝对定位元素。这时候儿子是否隐藏由爷爷决定,而不是老爸。
应用场景
明白了这个理论,对我们的工作有什么指导意义呢? 首先,我们知道overflow:hidden并不是万能的,要想彻底剪裁它的所有子元素,它不但要有overflow:hidden,而且还要作为所有子元素的包含块。这样万一某一天你看到overflow:hidden里面的东东居然被显示出来了,你才知道是为什么。 其次,如果我们先定义了overflow:hidden防止容器被撑开,或者用这个方法做了神马图文混排、清除浮动之类的处理,甚至是用了overflow:hidden来实现块级上下文这样上流的东东,突然产品又说里面的一个浮层要显示,要在右边,要在右上角,要在左边两个栏宽外面……那么你就知道要怎么搞了。
在oocss中,对模块的定义充分利用了这个特性。oocss的模块基本结构如下:
<div class="mod"> <div class="inner"> <div class="hd"></div> <div class="bd"></div> <div class="ft"></div> </div></div> |
他们就对inner应用了position:relative,对bd应用了overflow:hidden和_zoom:1。有兴趣的童靴可以研究一下。
作者:小李刀刀
原文链接:容易被误解的overflow:hidden
裁纸刀下版权所有,允许非商业用途转载,转载时请原样转载并标明来源、作者,保留原文链接。
本条目发布于2011-03-20。属于所谓技术分类,被贴了 CSS、overflow、技巧 标签。
容易被误解的overflow:hidden的更多相关文章
- overflow:hidden
原来以为overflow:hidden能隐藏所有溢出的子元素,但今天发现我错了. 对于overflow:hidden的最大误解时:当一个具有高度和宽度中至少一项的容器应用了overflow:hidde ...
- overflow:hidden失效
overflow:hidden失效 为了页面的健壮性,我们常常需要使用overflow:hidden.有时候是为了防止布局被撑开,有时候是为了配合其它规则实现文字截断,还有时候纯粹是为了创建块级上下文 ...
- overflow:hidden与margin:0 auto之间的冲突
相对于父容器水平居中的代码margin:0 auto与overflow:hidden之间存在冲突.当这两个属性同时应用在一个DIV上时,在chrome浏览器中将无法居中.至于为啥我也不明白.
- 移动端浏览器body的overflow:hidden并没有什么作用
今天突然遇到一个问题,使用li模拟select,但是碰到一个很尴尬的问题,给body加了overflow:hidden,但是body并没有禁止滚动条,滚动条依旧顺滑. <!DOCTYPE htm ...
- 解决overflow:hidden在安卓微信页面没有效果的办法
在做h5移动端时候,发现overflow: hidden;在安卓微信页面失效问题,经研究和实验,用第三种方法和第四种方法可以解决! 1.完全隐藏 在<boby>里加入scroll=&quo ...
- 在ie7中overflow:hidden失效问题及解决方案
css兼容ie7: 做页面的时候用负边距居中的时候在IE7下面,父节点中的overflow:hiden失效的问题,查阅了一些资料,总结一下解决方法. 问题原因: 当父元素的直接子元素或者下级子元素的样 ...
- overflow:hidden清楚浮动的影响
在网页布局中有时会遇到这种情况: 如果左边用<dt>,右边用<dd>,放在一行显示,<dt>要设置float:left,这个应该都知道,问题是,第一行这样做没有问题 ...
- 深入理解CSS溢出overflow & overflow:hidden真的失效了吗[转载]
深入理解CSS溢出overflow http://www.cnblogs.com/xiaohuochai/p/5289653.html overflow:hidden真的失效了吗 http://www ...
- 父容器根据子容器高度自适应:设置父容器 height:100%;overflow:hidden;
父容器根据子容器高度自适应:设置父容器 height:100%;overflow:hidden;
随机推荐
- 前端新人学习笔记-------html/css/js基础知识点(三)
这断时间家里有点事,上班也有点任务,所以几天没看视频没来更新了.今天来更新一下了. 一:默认样式重置 但凡是浏览默认的样式,都不要使用. body,p,h1,h2,h3,h4,h5,h6,dl,dd{ ...
- jQuery load()和ready()
ready与load谁先执行: 大家在面试的过程中,经常会被问到一个问题:ready与load那一个先执行,那一个后执行?答案是ready先执行,load后执行. DOM文档加载的步骤: 要想理解为什 ...
- SVN报错:can't open file db/txn-current-lock:permission denied 解决方法
其实这个问题是这样的.下面我举个例子:比如版本库SVN是root用户创建的但是启动服务的时候没有选择root启动,而是在其他用户转托管太下启动的,所以只能读不能写. 解决方法:停止svn服务:kill ...
- 1、 Linux中的root用户切换(转载)
su和su - 的区别 大部分Linux发行版的默认账户是普通用户,而更改系统文件或者执行某些命令,需要root身份才能进行,这就需要从当前用户切换到root用户,Linux中切换用户的命令是su或s ...
- navicat查看mysql数据表记录数不断变化
在使用navicat进行数据库管理的时候,在查看表对象的时候会发现,每次刷新,数据表的记录数不断变化,尤其是大表. 对于100万的数据经常会显示九十几万,当然通过count(*)出来的数据是正确的. ...
- Jexus 配置多个站点
一:jexus配置站点的文件在 siteconf文件夹中,里面有多少个配置文件,就可以配置多少个站点 如我的里面有3个配置文件,其中default是原始文件,site1和siteconf就是我网站的配 ...
- 关于NGINX下开启PHP-FPM 输出PHP错误日志的设置(已解决)
最近在本地搭建的LNMP的开发环境.为了开发的时候不影响前端的正常开发就屏蔽的PHP里面php.ini中的一些错误提示.但是这样一来,就影响到了后端开发的一些问题比如不能及时调试开发中的一些问题. n ...
- nginx 目录密码保护的设置方法
在 nginx.conf 文件中对应的 server 段中 添加 location ^~ /test/ { auth_basic TEST-Login; auth_basic_user_file /r ...
- c/c++:内存泄露和野指针的概念
内存泄漏 用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元.直到程序结束.即所谓内存泄漏. 注意:内存泄漏是指堆内存的泄漏. 简单的说就是申请了一块内存空间,使用 ...
- Orchard 源码探索(Module,Theme,Core扩展加载概述)
参考: http://www.orchardch.com/Blog/20120830071458 1. host.Initialize(); private static IOrchardHost H ...