1. 程式人生 > >css隱藏父元素,不隱藏子元素

css隱藏父元素,不隱藏子元素

一、CSS元素隱藏

在CSS中,讓元素隱藏(指螢幕範圍內肉眼不可見)的方法很多,有的佔據空間,有的不佔據空間;有的可以響應點選,有的不能響應點選。後宮選秀——一個一個看。

{ display: none; /* 不佔據空間,無法點選 */ }
{ visibility: hidden; /* 佔據空間,無法點選 */ }
{ position: absolute; clip:rect(1px 1px 1px 1px); /* 不佔據空間,無法點選 */ }
{ position: absolute; top: -999em; /* 不佔據空間,無法點選 */ }
{ position: relative; top: -999em; /* 佔據空間,無法點選 */
}
{ position: absolute; visibility: hidden; /* 不佔據空間,無法點選 */ }
{ height: 0; overflow: hidden; /* 不佔據空間,無法點選 */ }
{ opacity: 0; filter:Alpha(opacity=0); /* 佔據空間,可以點選 */ }
{ 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); 
    /* 不佔據空間,無法點選 */
}

歡迎補充!

以上隱藏方法如果針對最小輩的子元素(膝下無子女),例如<img>圖片元素,則上面的註釋說明都是OK的(若有誤,請指正)。

我以前就提過,為了便於理解,我們會使用情感化思維,類比現實,在內心形成只屬於自己的具象化的想法。這是很OK的,但是,要知道,事物是具有兩面的,具象的東西容易讓我們陷入固定思維模式,尤其在現實世界中非特殊情境的驗證下,從而讓我們不經意間產生一些錯誤的認識。

上面的話有點像老油條——難嚼。要讓老少皆懂,很簡單,舉幾個簡單的示例就可以了。而這裡的示例就是上頭幾個隱藏的例子:由於具象化的固定思維,您可能並不知道下面要提到的幾種CSS元素隱藏“失效”的情況!

二、display:none和visibility:hidden

我記得校園招聘那會兒,技術面的時候有問我display:nonevisibility:hidden的區別在哪兒?

“這個問題簡單?”我心裡頭暗自得意,按耐住自己得意又緊張的小心臟,自信滿滿地說,“這兩個宣告都可以讓元素隱藏,不同之處在於display:none隱藏後的元素不佔據任何空間,而visibility:hidden隱藏的元素空間依舊存在。”

想在想想,自己實在是浮躁了點。這種程度的答案說明你在HTML/CSS方面的造詣只是瞭解這個層面,並不能讓面試官眼前一亮。放眼整個中國,寫頁面的人何其多,像這種程度回答的人一定就像河裡的沙子一樣,一抓一大把。隨便用腳趾頭想想也知道,像度娘,企鵝公司花費那麼多人力和財力來校園是肯定來挑金子的,不起眼的沙子就讓它隨波逐流,流到大海暖化石去吧。

目前,我所知道的不同有三點(歡迎補充):

  1. 空間佔據
  2. 迴流與渲染
  3. 株連性

第一點,想必都知道;第二點我之前有多篇譯文提過,display:none隱藏產生reflow和repaint(迴流與重繪),而visibility:hidden沒有這個影響前端效能的問題;第三點估計是不少同行不知道的,就是“株連性”方面的差異。

所謂“株連性”,就是如果祖先元素遭遇某禍害,則其子子孫孫無一例外也要遭殃。我頓時想起了《地球反擊戰》或是《木乃伊之蠍子王》,一旦把母體搞跛了,小輩啊、下屬啊什麼的都瞬間煙消雲散。display:none就是“株連性”明顯的宣告:一旦父節點元素應用了display:none,父節點及其子孫節點元素全部不可見,而且無論其子孫元素如何不屈地掙扎都無濟於事。

在實際的web應用中,我們要經常實現一些顯示隱藏的功能,由於display:none本身特性以及jQuery潛在的驅動,使得我們對display:none這種隱藏特性相當熟知。因此,久而久之會形成比較牢固的情感化認識,並無法避免地將這種認識遷移到其他類似表現屬性(eg. visibility)的認識上,再加上一些常規經驗……

舉例來說吧,通常情況下,我們給一個父元素應用visibility:hidden,則其子孫後代也都會全部不可見。於是,我們就會有類似的認識遷移:應用了visibility:hidden宣告下的子孫元素如何不屈地掙扎都擺脫不了不可見被抹殺的命運。而實際上卻存在隱藏“失效”的情況。

何時隱藏“失效”?很簡單,如果子孫元素應用了visibility:visible,那麼這個子孫元素又會劉謙般地顯現出來。

visibility屬性的覆蓋性測試頁面截圖標註示意

visibility就是這樣一個funny的屬性。

對比總結:
display:none是個相當慘無人道的宣告,子孫後代全部搞死(株連性),而且連塊安葬的地方都不留(不留空間),導致全體民眾譁然(渲染與迴流)。
visibility:hidden則具有人道主義關懷,雖然不得已搞死子孫,但是子孫可以通過一定手段避免(偽株連性),而且死後全屍,墓地俱全(佔據空間),國內民眾比較淡然(無渲染與迴流)。

可以看到demo頁面中張美女都跟靚仔過情人節去了。

三、visibility隱藏“失效”妙用

visibility隱藏“失效” 的應用其實在老早的時候就有了,等下,讓我找找~~

CSS3模擬window7炫酷介面效果截圖 張鑫旭-鑫空間-鑫生活

檢視對應核心CSS程式碼 張鑫旭-鑫空間-鑫生活

複選框勾選與否對應的部分顯示與隱藏。例如,偶們要讓父標籤的圓角啊、投影啊、背景啊什麼的都隱掉,只留裡面的文字框。該怎麼實現?如果是要display:none,則裡面的文字框框也會被一併抹殺掉的,如果是要指令碼控制style,哇哦哦,這麼多樣式,想想腦袋就大了。毋庸置疑,這裡使用visibility控制是最高效也是最巧妙的方法。

四、height:0和overflow:hidden的組合

overflow:hidden用中文理解就是“溢位隱藏”,也就是盒子以外的內容都咔嚓掉不可見的。加上height:0,只要是一般的非inline水平元素,則元素內部所有子孫都應該是不可見的。這是我們具象化的認識,而且N多的經驗驗證都是如此,但是實際上是這樣子嗎?

height:0和overflow:hidden失效的例子截圖

height:0overflow:hidden組合隱藏“失效”的條件如下:祖先元素沒有position:relative/absolute/fixed宣告,同時內部子元素應用了position:absolute/fixed宣告。

為什麼會這樣?
先看下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可以剪裁超出塊狀元素之外的元素。除非超出元素的包含塊是整個視區或是該overflow元素的祖先元素。然後絕對定位元素的包含塊應該就是含有position:relative/absolute/fixed的祖先元素。

因此:

body
    height: 0; overflow: hidden;
        position: absolute; /* 不會被隱藏 */
position: relative;
    height: 0; overflow: hidden;
        position: absolute; /* 不會被隱藏 */
height: 0; overflow: hidden;  position: relative;
    position: absolute; /* 會被隱藏 */
height: 0; overflow: hidden;
    position: relative;
        position: absolute; /* 會被隱藏 */

記住這個:position: absolute元素溢位overflow: hidden元素的時候,如果其第一個含有position屬性(static除外)的祖先元素(一直到body)是overflow: hidden元素祖先元素的時候,則不隱藏;否則,隱藏。

或者記住這個:火星人在地球觸發了法律,如果火星人的老爸在這法律之外,則這個火星人啥事沒有;否則,坐牢!

五、height:0和overflow:hidden“失效”妙用

後來有人反映,此方法好是好,但是有一個問題,因為標籤內打了個&nbsp;空格,產生了了空白高度啊!

如何fix這裡的空格產生的高度呢?使用line-height: 0; ? 或者使用font-size: 0;? 如果不是因為line-heightfont-size具有繼承性,這確實是個好方法(font-size還有Chrome預設文字無法小於12畫素問題,考古版本IE下0畫素文字呈現小點的問題)。

經過我多方測試,以在OOCSS開發模式下,這裡使用height:0overflow:hidden是最好的方法。

h0 ovh tr
    &nbsp; abs

使用height:0 overflow:hidden實現不佔據空間 張鑫旭-鑫空間-鑫生活

demo中,上面一個條條&nbsp;產生高度,因此頭部背景色,而下面這個條條就沒有。因為定位元素是絕對定位的,因此,不要擔心會被overflow不小心幹掉!

六、情人節結語

據說今天 @淘寶超仁 花了10W在淘寶上買了個廣告位向 @倩小蓮 表白。
淘寶首頁情人節表白 張鑫旭-鑫空間-鑫生活

這位哥們真是大手筆啊,我輩實在望塵莫及,只能用毛主席換些德芙了。想了想,擠不出設麼話了,就這樣吧。

末了,再附上一個opacity透明度覆蓋性測試demo,您可以狠狠地點選這裡:opacity透明度覆蓋性測試demo

結果顯示,透明度屬性會重疊,具有覆蓋性。

(本篇完)