子元素获取父元素(未定义高度)的高度详解:

浏览器参照基准:Firefox, Chrome, Safari, Opera, IE

* 你可能碰到过这样的需求,一个高度不固定的区域(内容由用户创造),当鼠标经过该区域或者其神马操作时,需要出现一个与该区域一样大的蒙版(mask)

Figure 1:举个不太恰当的例子,如下图
典型的瀑布流效果中,每个张图的高度都可能不同,

* 如上图,两个图片区域的高度不一致,同时也不能给它们定义高度,但鼠标经过这些区域时都会有灰色蒙版操作,且这个蒙版的高度要等于图片区域的高度,我知道,你要说js获取一下图片高度既可,可是我们可以更简单一点吗?

Figure 2:我们试着抽取这样一个简单的结构 DEMO
<div id="demo"> <div class="sample-1"><p>我的高度其实是没有定义的,内容有多少我就有多高。</p></div> <div class="sample-2"><p>我的高度其实是没有定义的,内容有多少我就有多高。我的高度其实是没有定义的,内容有多少我就有多高。</p></div> </div>

* 查看上面的Figure #2DEMO,你会看到两个高度不同的区块,假设这种区块的高度是不可以预设的,我想在每个区块上覆盖满一个mask,我要怎么做?

Figure 3:加上mask结构 DEMO
<div id="demo"> <div class="sample-1"><p>我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> <div class="sample-2"><p>我的高度其实是没有定义的,内容有多少我就有多高。我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> </div>

* 一切从简,我们用一个span来处理这个mask。由于 .sample-1 和 .sample-2 的高度是不确定的,也就是说我们没有对它们定义 height, 头痛的问题来了,如果父元素没有定义高度,子元素是否仍然可以通过 height:100% 的方式来得到父元素的实际高度呢?

Figure 4:try DEMO
<div id="demo"> <div class="sample-1"><p>我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> <div class="sample-2"><p>我的高度其实是没有定义的,内容有多少我就有多高。我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> </div> #demo div{ position:relative; width:300px; } #demo span{ position:absolute; top:0; left:0; width:100%; height:100%; }

* 通过本例的DEMO,你会惊喜的发现除了IE6,几乎所有的主流浏览器都支持子元素获取父元素(未定义高度)的高度;是不是兴奋的同时又有点沮丧,Fuck IE6!

* 怎么办?用js?当然可以,本文到此结束。一个玩笑,虽然IE6无法支持,但是否可以有变通的方法可以达到相同效果呢?

* 还记得当年实现多列等高的风靡一时的方法吗?正padding + 负margin,最终实现视觉上的等高,这里是否也可以借鉴一下呢?

Figure 5:你是否想到了用padding? DEMO
<div id="demo"> <div class="sample-1"><p>我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> <div class="sample-2"><p>我的高度其实是没有定义的,内容有多少我就有多高。我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> </div> #demo div{ position:relative; width:300px; } #demo span{ position:absolute; top:0; left:0; width:100%; height:100%; _padding-bottom:500px; }

* 对于这个用户创造内容的区域,高度会在一个什么范围内,我想你是会有一个预期的,你可以定义一个适当的padding值,如果实在无法预期,那你不妨将这个值定义大一点;

* 我随意将padding-bottom定义为500px,因为在我这个例子的场景里这个值已经足够了,用IE6看看 DEMO,坏了,mask层溢出了父层,怎么办?

Figure 5:试试overflow? DEMO
<div id="demo"> <div class="sample-1"><p>我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> <div class="sample-2"><p>我的高度其实是没有定义的,内容有多少我就有多高。我的高度其实是没有定义的,内容有多少我就有多高。</p><span class="mask"></span></div> </div> #demo div{ position:relative; _overflow:hidden; width:300px; } #demo span{ position:absolute; top:0; left:0; width:100%; height:100%; _padding-bottom:500px; }

* 看看效果如何 DEMO,貌似正是我们想要的效果。

* 很多时候不要太去在意某浏览器是否支持某特性,因为支持就是支持,不支持就是不支持;当你沉下心来,或许会有很多变通的方式去达到你想要的效果。

CSS探索之旅